pyScss-1.1.5/0000755000076500000240000000000012107522130013446 5ustar kronuzstaff00000000000000pyScss-1.1.5/CHANGELOG0000644000076500000240000000355012107521210014661 0ustar kronuzstaff00000000000000Changelog ========= 1.1.5 Feb 15, 2013 + ``debug_info`` now properly produces rules that can be used by FireSass and Google Chrome SASS Source Maps. + Improved memory usage for large sets of files to be used as sprites. + Warns about IE 4095 maximum number of selectors. + ``debug_info`` prints info as comments if specified as ``comments``. + Better handling of undefined variables. + Added CSS filter functions and ``skewX`` ``skewY``. + Command line tool and entry point fixed. + Fix cache buster URLs when paths already include queries or fragments. + Hashable Values. 1.1.4 Aug 8, 2012 + Added ``--debug-info`` command line option (for *FireSass* output). + Added compass helper function ``reject()``. + Added ``undefined`` keyword for undefined variables. 1.1.3 Jan 9, 2012 + Support for the new Sass 3.2.0 features (``@content`` and placeholder selectors) + Fixed bug with line numbers throwing an exception. 1.1.2 Jan 3, 2012 + Regression bug fixed from 1.1.1 1.1.1 Jan 2, 2012 + Added optional C speedup module for an amazing boost in scanning speed! + Added ``headings``, ``stylesheet-url``, ``font-url``, ``font-files``, ``inline-font-files`` and ``sprite-names``. 1.1.0 - Dec 22, 2011 + Added ``min()`` and ``max()`` for lists. + Removed exception raise. 1.0.9 - Dec 22, 2011 + Optimizations in the scanner. + Added ``background-noise()`` for compass-recipes support. + ``enumerate()`` and ``range()`` can go backwards. Ex.: ``range(3, 0)`` goes from 3 to 0. + Added line numbers and files for errors. + Added support for *Firebug* with *FireSass*. + ``nth(n)`` is round (returns the ``nth mod len`` item of the list). + ``--watch`` added to the command line. + Several bugs fixed. 1.0.8 - May 13, 2011 + Changed source color (``$src-color``) default to black. + Moved the module filename to ``__init__.py`` and module renamed back to scss. pyScss-1.1.5/DESCRIPTION0000644000076500000240000000004211532260154015156 0ustar kronuzstaff00000000000000pyScss, a Scss compiler for PythonpyScss-1.1.5/LICENSE0000644000076500000240000000210211703162332014453 0ustar kronuzstaff00000000000000The MIT License Copyright (c) 2011, 2012 German M. Bravo (Kronuz) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.pyScss-1.1.5/MANIFEST.in0000644000076500000240000000011211700502134015176 0ustar kronuzstaff00000000000000include DESCRIPTION LICENSE CHANGELOG README.rst recursive-include scss * pyScss-1.1.5/PKG-INFO0000644000076500000240000003752012107522130014552 0ustar kronuzstaff00000000000000Metadata-Version: 1.0 Name: pyScss Version: 1.1.5 Summary: pyScss, a Scss compiler for Python Home-page: http://github.com/Kronuz/pyScss Author: German M. Bravo (Kronuz) Author-email: german.mb@gmail.com License: MIT Download-URL: http://github.com/Kronuz/pyScss/tarball/v1.1.5 Description: pyScss, a Scss compiler for Python ================================== :Author: German M. Bravo (Kronuz) About ===== pyScss compiles Scss (Sass), a superset of CSS that is more powerful, elegant and easier to maintain than plain-vanilla CSS. The library acts as a CSS source code preprocesor which allows you to use variables, nested rules, mixins, and have inheritance of rules, all with a CSS-compatible syntax which the preprocessor then compiles to standard CSS. Scss, as an extension of CSS, helps keep large stylesheets well-organized. It borrows concepts and functionality from projects such as OOCSS and other similar frameworks like as Sass. It's build on top of the original PHP xCSS codebase structure but it's been completely rewritten, many bugs have been fixed and it has been extensively extended to support almost the full range of Sass' Scss syntax and functionality. .. image:: http://pledgie.com/campaigns/16513.png?skin_name=chrome :alt: Click here to lend your support to pyScss and make a donation at pledgie.com! :target: http://pledgie.com/campaigns/16513 Support ======== pyScss is fully compatible with SCSS (Sass) 3.2 ...it has: * **Compass**: Compass 0.11 Support * **Nested rules** * **Keyword arguments** * **Mixins**: `@mixin`, `@include` * **Functions**: `@function`, `@return` * **Inheritance**: `@extend` * **Conditions**: `@if`, `@else if`, `@else` * **Loops**: `@for`, `@each` * **Variables**: `$`, `@variables`, `@vars` * **Sprites**: `sprite-map()`, `sprite()`, `sprite-position()`, `sprite-url()`, ... * **Images**: `image-url()`, `image-width()`, `image-height()`, ... * **Embedded (inline) images**: `inline-image()` * **Colors handling**: `adjust-color()`, `scale-color()`, `opacify()`/`transparentize()`, `lighten()`/`darken()`, `mix()`, ... * **Math functions**: `sin()`, `cos()`, `tan()`, `round()`, `ceil()`, `floor()`, `pi()`, ... * **CSS Compression**: `@option compress:yes;` Requirements ============ * python >= 2.5 Installation ============ pyScss should be installed using pip or setuptools:: pip install pyScss easy_install pyScss Usage ===== Usage example:: from scss import Scss css = Scss() css.compile("a { color: red + green; }") Or compile from the command line:: python -mscss < file.scss Interactive mode:: python -mscss --interactive .. note:: ``-mscss`` will only work in Python 2.7 and above, for Python 2.5 and 2.6 you need to invoke:: python -mscss.tool Examples ======== #. **Nested Rules** Example:: @option compress: no; .selector { a { display: block; } strong { color: blue; } } ...produces:: .selector a { display: block; } .selector strong { color: #00f; } #. **Variables** Example:: @option compress: no; $main-color: #ce4dd6; $style: solid; $side: bottom; #navbar { border-#{$side}: { color: $main-color; style: $style; } } ...produces:: #navbar { border-bottom-color: #ce4dd6; border-bottom-style: solid; } #. **Mixins** Example:: @option compress: no; @mixin rounded($side, $radius: 10px) { border-#{$side}-radius: $radius; -moz-border-radius-#{$side}: $radius; -webkit-border-#{$side}-radius: $radius; } #navbar li { @include rounded(top); } #footer { @include rounded(top, 5px); } #sidebar { @include rounded(left, 8px); } ...produces:: #navbar li { border-top-radius: 10px; -moz-border-radius-top: 10px; -webkit-border-top-radius: 10px; } #footer { border-top-radius: 5px; -moz-border-radius-top: 5px; -webkit-border-top-radius: 5px; } #sidebar { border-left-radius: 8px; -moz-border-radius-left: 8px; -webkit-border-left-radius: 8px; } #. **Extend** (using `@extend`) Example:: @option compress: no; .error { border: 1px #f00; background-color: #fdd; } .error.intrusion { background-image: url("/image/hacked.png"); } .seriousError { @extend .error; border-width: 3px; } ...produces:: .error, .seriousError { border: 1px red; background-color: #fdd; } .error.intrusion, .seriousError.intrusion { background-image: url("/image/hacked.png"); } .seriousError { border-width: 3px; } #. **Sprites** (using `sprite-map()`) Example:: @option compress: no; $icons: sprite-map("sociable/*.png"); // contains sociable/facebook.png among others. div { background: $icons; } @each $icon in sprites($icons) { div .#{$icon} { width: image-width(sprite-file($icons, $icon)); height: image-height(sprite-file($icons, $icon)); background-position: sprite-position($icons, $icon); } } ...generates a new sprite file and produces something like:: div { background: url("/static/assets/u8Y7yEQL0UffAVw5rX7yhw.png?_=1298240989") 0px 0px no-repeat; } div .facebook { width: 32px; height: 32px; background-position: 0px 0px; } div .twitter { width: 32px; height: 32px; background-position: 0px -32px; } ... #. **Interactive mode** Example:: $ python scss.py --interactive >>> @import "compass/css3" >>> show() ['functions', 'mixins', 'options', 'vars'] >>> show(mixins) ['apply-origin', 'apply-transform', ... 'transparent'] >>> show(mixins, transparent) @mixin transparent() { @include opacity(0); } >>> 1px + 5px 6px >>> _ Sass Sassy CSS ============== pyScss is a Scss (Sass) implementation for Python. Currently it implements @mixin, @include, @if, @else, @for, and @import... it also implements many of the Sass functions including color functions like hsla(), hsl(), darken(), lighten(), mix(), opacify(), transparentize(), saturate(), desaturate(), etc.) as well as sprite-map(), sprite-file(), image-width(), image-height() and the others. In the file `scss.py`, by the top, you can configure the LOAD_PATHS to point to your Sass frameworks path (I have `sass/frameworks/compass/*.scss` and `sass/framework/blueprint/*.scss` files in my project directory: `/usr/local/www/project/`, where `scss.py` lives, so it defaults to use the `sass/framework/` path, relative to the `scss.py` file) or configure using the command line `--load-path` option, see `python scss.py --help`. I have succesfully compiled some Compass using `python scss.py < myfile.css` the following `myfile.css`:: @option compress: no; $blueprint-grid-columns : 24; $blueprint-grid-width : 30px; $blueprint-grid-margin : 10px; $font-color : #333; @import "compass/reset"; @import "compass/utilities"; @import "blueprint"; // Stuff goes here... Django Example ============== The following shows some code that can be used with django:: import os import fnmatch import scss from django.conf import settings from django.utils.datastructures import SortedDict from django.contrib.staticfiles import finders def finder(glob): """ Finds all files in the django finders for a given glob, returns the file path, if available, and the django storage object. storage objects must implement the File storage API: https://docs.djangoproject.com/en/dev/ref/files/storage/ """ for finder in finders.get_finders(): for path, storage in finder.list([]): if fnmatch.fnmatchcase(path, glob): yield path, storage # STATIC_ROOT is where pyScss looks for images and static data. # STATIC_ROOT can be either a fully qualified path name or a "finder" # iterable function that receives a filename or glob and returns a tuple # of the file found and its file storage object for each matching file. # (https://docs.djangoproject.com/en/dev/ref/files/storage/) scss.STATIC_ROOT = finder scss.STATIC_URL = settings.STATIC_URL # ASSETS_ROOT is where the pyScss outputs the generated files such as spritemaps # and compile cache: scss.ASSETS_ROOT = os.path.join(settings.MEDIA_ROOT, 'assets/') scss.ASSETS_URL = settings.MEDIA_URL + 'assets/' # These are the paths pyScss will look ".scss" files on. This can be the path to # the compass framework or blueprint or compass-recepies, etc. scss.LOAD_PATHS = [ '/usr/local/www/sass/frameworks/', '/Library/Ruby/Gems/1.8/gems/compass-0.11.5/frameworks/compass/stylesheets/', '/Library/Ruby/Gems/1.8/gems/compass-0.11.5/frameworks/blueprint/stylesheets/', ] # This creates the Scss object used to compile SCSS code. In this example, # _scss_vars will hold the context variables: _scss_vars = {} _scss = scss.Scss( scss_vars=_scss_vars, scss_opts={ 'compress': True, 'debug_info': True, } ) # 1. Compile from a string: compiled_css_from_string = _scss.compile('@import "file2"; a {color: red + green; }') # 2. Compile from a file: compiled_css_from_file = _scss.compile(scss_file='file1.scss') # 3. Compile from a set of files (use SortedDict or collections.OrderedDict to # maintain the compile order): _scss._scss_files = SortedDict(( ('file2.scss', open('file2.scss').read()), ('file3.scss', open('file3.scss').read()), ('file4.scss', open('file4.scss').read()), )) compiled_css_from_files = _scss.compile() Bug tracker =========== If you have any suggestions, bug reports or annoyances please report them to the issue tracker at http://github.com/Kronuz/pyScss/issues Changelog ========= 1.1.5 Feb 15, 2013 + ``debug_info`` now properly produces rules that can be used by FireSass and Google Chrome SASS Source Maps. + Improved memory usage for large sets of files to be used as sprites. + Warns about IE 4095 maximum number of selectors. + ``debug_info`` prints info as comments if specified as ``comments``. + Better handling of undefined variables. + Added CSS filter functions and ``skewX`` ``skewY``. + Command line tool and entry point fixed. + Fix cache buster URLs when paths already include queries or fragments. + Hashable Values. 1.1.4 Aug 8, 2012 + Added ``--debug-info`` command line option (for *FireSass* output). + Added compass helper function ``reject()``. + Added ``undefined`` keyword for undefined variables. 1.1.3 Jan 9, 2012 + Support for the new Sass 3.2.0 features (``@content`` and placeholder selectors) + Fixed bug with line numbers throwing an exception. 1.1.2 Jan 3, 2012 + Regression bug fixed from 1.1.1 1.1.1 Jan 2, 2012 + Added optional C speedup module for an amazing boost in scanning speed! + Added ``headings``, ``stylesheet-url``, ``font-url``, ``font-files``, ``inline-font-files`` and ``sprite-names``. 1.1.0 - Dec 22, 2011 + Added ``min()`` and ``max()`` for lists. + Removed exception raise. 1.0.9 - Dec 22, 2011 + Optimizations in the scanner. + Added ``background-noise()`` for compass-recipes support. + ``enumerate()`` and ``range()`` can go backwards. Ex.: ``range(3, 0)`` goes from 3 to 0. + Added line numbers and files for errors. + Added support for *Firebug* with *FireSass*. + ``nth(n)`` is round (returns the ``nth mod len`` item of the list). + ``--watch`` added to the command line. + Several bugs fixed. 1.0.8 - May 13, 2011 + Changed source color (``$src-color``) default to black. + Moved the module filename to ``__init__.py`` and module renamed back to scss. Contributing ============ Development of pyScss happens at github: https://github.com/Kronuz/pyScss License ======= MIT License. See *LICENSE* for details. http://www.opensource.org/licenses/mit-license.php Copyright ========= Copyright (c) 2012 German M. Bravo (Kronuz) *Bits of code in pyScss come from various projects:* Compass: (c) 2009 Christopher M. Eppstein http://compass-style.org/ Sass: (c) 2006-2009 Hampton Catlin and Nathan Weizenbaum http://sass-lang.com/ xCSS: (c) 2010 Anton Pawlik http://xcss.antpaw.org/docs/ Keywords: css oocss xcss sass scss less precompiler Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Software Development :: Code Generators Classifier: Topic :: Text Processing :: Markup Classifier: Topic :: Software Development :: Libraries :: Python Modules pyScss-1.1.5/pyScss.egg-info/0000755000076500000240000000000012107522130016424 5ustar kronuzstaff00000000000000pyScss-1.1.5/pyScss.egg-info/dependency_links.txt0000644000076500000240000000000112107522130022472 0ustar kronuzstaff00000000000000 pyScss-1.1.5/pyScss.egg-info/entry_points.txt0000644000076500000240000000010312107522130021714 0ustar kronuzstaff00000000000000 [console_scripts] pyscss = scss.tool:main pyScss-1.1.5/pyScss.egg-info/PKG-INFO0000644000076500000240000003752012107522130017530 0ustar kronuzstaff00000000000000Metadata-Version: 1.0 Name: pyScss Version: 1.1.5 Summary: pyScss, a Scss compiler for Python Home-page: http://github.com/Kronuz/pyScss Author: German M. Bravo (Kronuz) Author-email: german.mb@gmail.com License: MIT Download-URL: http://github.com/Kronuz/pyScss/tarball/v1.1.5 Description: pyScss, a Scss compiler for Python ================================== :Author: German M. Bravo (Kronuz) About ===== pyScss compiles Scss (Sass), a superset of CSS that is more powerful, elegant and easier to maintain than plain-vanilla CSS. The library acts as a CSS source code preprocesor which allows you to use variables, nested rules, mixins, and have inheritance of rules, all with a CSS-compatible syntax which the preprocessor then compiles to standard CSS. Scss, as an extension of CSS, helps keep large stylesheets well-organized. It borrows concepts and functionality from projects such as OOCSS and other similar frameworks like as Sass. It's build on top of the original PHP xCSS codebase structure but it's been completely rewritten, many bugs have been fixed and it has been extensively extended to support almost the full range of Sass' Scss syntax and functionality. .. image:: http://pledgie.com/campaigns/16513.png?skin_name=chrome :alt: Click here to lend your support to pyScss and make a donation at pledgie.com! :target: http://pledgie.com/campaigns/16513 Support ======== pyScss is fully compatible with SCSS (Sass) 3.2 ...it has: * **Compass**: Compass 0.11 Support * **Nested rules** * **Keyword arguments** * **Mixins**: `@mixin`, `@include` * **Functions**: `@function`, `@return` * **Inheritance**: `@extend` * **Conditions**: `@if`, `@else if`, `@else` * **Loops**: `@for`, `@each` * **Variables**: `$`, `@variables`, `@vars` * **Sprites**: `sprite-map()`, `sprite()`, `sprite-position()`, `sprite-url()`, ... * **Images**: `image-url()`, `image-width()`, `image-height()`, ... * **Embedded (inline) images**: `inline-image()` * **Colors handling**: `adjust-color()`, `scale-color()`, `opacify()`/`transparentize()`, `lighten()`/`darken()`, `mix()`, ... * **Math functions**: `sin()`, `cos()`, `tan()`, `round()`, `ceil()`, `floor()`, `pi()`, ... * **CSS Compression**: `@option compress:yes;` Requirements ============ * python >= 2.5 Installation ============ pyScss should be installed using pip or setuptools:: pip install pyScss easy_install pyScss Usage ===== Usage example:: from scss import Scss css = Scss() css.compile("a { color: red + green; }") Or compile from the command line:: python -mscss < file.scss Interactive mode:: python -mscss --interactive .. note:: ``-mscss`` will only work in Python 2.7 and above, for Python 2.5 and 2.6 you need to invoke:: python -mscss.tool Examples ======== #. **Nested Rules** Example:: @option compress: no; .selector { a { display: block; } strong { color: blue; } } ...produces:: .selector a { display: block; } .selector strong { color: #00f; } #. **Variables** Example:: @option compress: no; $main-color: #ce4dd6; $style: solid; $side: bottom; #navbar { border-#{$side}: { color: $main-color; style: $style; } } ...produces:: #navbar { border-bottom-color: #ce4dd6; border-bottom-style: solid; } #. **Mixins** Example:: @option compress: no; @mixin rounded($side, $radius: 10px) { border-#{$side}-radius: $radius; -moz-border-radius-#{$side}: $radius; -webkit-border-#{$side}-radius: $radius; } #navbar li { @include rounded(top); } #footer { @include rounded(top, 5px); } #sidebar { @include rounded(left, 8px); } ...produces:: #navbar li { border-top-radius: 10px; -moz-border-radius-top: 10px; -webkit-border-top-radius: 10px; } #footer { border-top-radius: 5px; -moz-border-radius-top: 5px; -webkit-border-top-radius: 5px; } #sidebar { border-left-radius: 8px; -moz-border-radius-left: 8px; -webkit-border-left-radius: 8px; } #. **Extend** (using `@extend`) Example:: @option compress: no; .error { border: 1px #f00; background-color: #fdd; } .error.intrusion { background-image: url("/image/hacked.png"); } .seriousError { @extend .error; border-width: 3px; } ...produces:: .error, .seriousError { border: 1px red; background-color: #fdd; } .error.intrusion, .seriousError.intrusion { background-image: url("/image/hacked.png"); } .seriousError { border-width: 3px; } #. **Sprites** (using `sprite-map()`) Example:: @option compress: no; $icons: sprite-map("sociable/*.png"); // contains sociable/facebook.png among others. div { background: $icons; } @each $icon in sprites($icons) { div .#{$icon} { width: image-width(sprite-file($icons, $icon)); height: image-height(sprite-file($icons, $icon)); background-position: sprite-position($icons, $icon); } } ...generates a new sprite file and produces something like:: div { background: url("/static/assets/u8Y7yEQL0UffAVw5rX7yhw.png?_=1298240989") 0px 0px no-repeat; } div .facebook { width: 32px; height: 32px; background-position: 0px 0px; } div .twitter { width: 32px; height: 32px; background-position: 0px -32px; } ... #. **Interactive mode** Example:: $ python scss.py --interactive >>> @import "compass/css3" >>> show() ['functions', 'mixins', 'options', 'vars'] >>> show(mixins) ['apply-origin', 'apply-transform', ... 'transparent'] >>> show(mixins, transparent) @mixin transparent() { @include opacity(0); } >>> 1px + 5px 6px >>> _ Sass Sassy CSS ============== pyScss is a Scss (Sass) implementation for Python. Currently it implements @mixin, @include, @if, @else, @for, and @import... it also implements many of the Sass functions including color functions like hsla(), hsl(), darken(), lighten(), mix(), opacify(), transparentize(), saturate(), desaturate(), etc.) as well as sprite-map(), sprite-file(), image-width(), image-height() and the others. In the file `scss.py`, by the top, you can configure the LOAD_PATHS to point to your Sass frameworks path (I have `sass/frameworks/compass/*.scss` and `sass/framework/blueprint/*.scss` files in my project directory: `/usr/local/www/project/`, where `scss.py` lives, so it defaults to use the `sass/framework/` path, relative to the `scss.py` file) or configure using the command line `--load-path` option, see `python scss.py --help`. I have succesfully compiled some Compass using `python scss.py < myfile.css` the following `myfile.css`:: @option compress: no; $blueprint-grid-columns : 24; $blueprint-grid-width : 30px; $blueprint-grid-margin : 10px; $font-color : #333; @import "compass/reset"; @import "compass/utilities"; @import "blueprint"; // Stuff goes here... Django Example ============== The following shows some code that can be used with django:: import os import fnmatch import scss from django.conf import settings from django.utils.datastructures import SortedDict from django.contrib.staticfiles import finders def finder(glob): """ Finds all files in the django finders for a given glob, returns the file path, if available, and the django storage object. storage objects must implement the File storage API: https://docs.djangoproject.com/en/dev/ref/files/storage/ """ for finder in finders.get_finders(): for path, storage in finder.list([]): if fnmatch.fnmatchcase(path, glob): yield path, storage # STATIC_ROOT is where pyScss looks for images and static data. # STATIC_ROOT can be either a fully qualified path name or a "finder" # iterable function that receives a filename or glob and returns a tuple # of the file found and its file storage object for each matching file. # (https://docs.djangoproject.com/en/dev/ref/files/storage/) scss.STATIC_ROOT = finder scss.STATIC_URL = settings.STATIC_URL # ASSETS_ROOT is where the pyScss outputs the generated files such as spritemaps # and compile cache: scss.ASSETS_ROOT = os.path.join(settings.MEDIA_ROOT, 'assets/') scss.ASSETS_URL = settings.MEDIA_URL + 'assets/' # These are the paths pyScss will look ".scss" files on. This can be the path to # the compass framework or blueprint or compass-recepies, etc. scss.LOAD_PATHS = [ '/usr/local/www/sass/frameworks/', '/Library/Ruby/Gems/1.8/gems/compass-0.11.5/frameworks/compass/stylesheets/', '/Library/Ruby/Gems/1.8/gems/compass-0.11.5/frameworks/blueprint/stylesheets/', ] # This creates the Scss object used to compile SCSS code. In this example, # _scss_vars will hold the context variables: _scss_vars = {} _scss = scss.Scss( scss_vars=_scss_vars, scss_opts={ 'compress': True, 'debug_info': True, } ) # 1. Compile from a string: compiled_css_from_string = _scss.compile('@import "file2"; a {color: red + green; }') # 2. Compile from a file: compiled_css_from_file = _scss.compile(scss_file='file1.scss') # 3. Compile from a set of files (use SortedDict or collections.OrderedDict to # maintain the compile order): _scss._scss_files = SortedDict(( ('file2.scss', open('file2.scss').read()), ('file3.scss', open('file3.scss').read()), ('file4.scss', open('file4.scss').read()), )) compiled_css_from_files = _scss.compile() Bug tracker =========== If you have any suggestions, bug reports or annoyances please report them to the issue tracker at http://github.com/Kronuz/pyScss/issues Changelog ========= 1.1.5 Feb 15, 2013 + ``debug_info`` now properly produces rules that can be used by FireSass and Google Chrome SASS Source Maps. + Improved memory usage for large sets of files to be used as sprites. + Warns about IE 4095 maximum number of selectors. + ``debug_info`` prints info as comments if specified as ``comments``. + Better handling of undefined variables. + Added CSS filter functions and ``skewX`` ``skewY``. + Command line tool and entry point fixed. + Fix cache buster URLs when paths already include queries or fragments. + Hashable Values. 1.1.4 Aug 8, 2012 + Added ``--debug-info`` command line option (for *FireSass* output). + Added compass helper function ``reject()``. + Added ``undefined`` keyword for undefined variables. 1.1.3 Jan 9, 2012 + Support for the new Sass 3.2.0 features (``@content`` and placeholder selectors) + Fixed bug with line numbers throwing an exception. 1.1.2 Jan 3, 2012 + Regression bug fixed from 1.1.1 1.1.1 Jan 2, 2012 + Added optional C speedup module for an amazing boost in scanning speed! + Added ``headings``, ``stylesheet-url``, ``font-url``, ``font-files``, ``inline-font-files`` and ``sprite-names``. 1.1.0 - Dec 22, 2011 + Added ``min()`` and ``max()`` for lists. + Removed exception raise. 1.0.9 - Dec 22, 2011 + Optimizations in the scanner. + Added ``background-noise()`` for compass-recipes support. + ``enumerate()`` and ``range()`` can go backwards. Ex.: ``range(3, 0)`` goes from 3 to 0. + Added line numbers and files for errors. + Added support for *Firebug* with *FireSass*. + ``nth(n)`` is round (returns the ``nth mod len`` item of the list). + ``--watch`` added to the command line. + Several bugs fixed. 1.0.8 - May 13, 2011 + Changed source color (``$src-color``) default to black. + Moved the module filename to ``__init__.py`` and module renamed back to scss. Contributing ============ Development of pyScss happens at github: https://github.com/Kronuz/pyScss License ======= MIT License. See *LICENSE* for details. http://www.opensource.org/licenses/mit-license.php Copyright ========= Copyright (c) 2012 German M. Bravo (Kronuz) *Bits of code in pyScss come from various projects:* Compass: (c) 2009 Christopher M. Eppstein http://compass-style.org/ Sass: (c) 2006-2009 Hampton Catlin and Nathan Weizenbaum http://sass-lang.com/ xCSS: (c) 2010 Anton Pawlik http://xcss.antpaw.org/docs/ Keywords: css oocss xcss sass scss less precompiler Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Software Development :: Code Generators Classifier: Topic :: Text Processing :: Markup Classifier: Topic :: Software Development :: Libraries :: Python Modules pyScss-1.1.5/pyScss.egg-info/SOURCES.txt0000644000076500000240000000153012107522130020307 0ustar kronuzstaff00000000000000CHANGELOG DESCRIPTION LICENSE MANIFEST.in README.rst setup.py pyScss.egg-info/PKG-INFO pyScss.egg-info/SOURCES.txt pyScss.egg-info/dependency_links.txt pyScss.egg-info/entry_points.txt pyScss.egg-info/top_level.txt scss/.DS_Store scss/__init__.py scss/__init__.pyc scss/__main__.py scss/_speedups.so scss/config.py scss/config.pyc scss/scss_meta.py scss/scss_meta.pyc scss/setup.py scss/tests.rst scss/tool.py scss/tool.pyc scss/src/.DS_Store scss/src/_speedups.c scss/src/_speedups.o scss/src/block_locator.c scss/src/block_locator.h scss/src/block_locator.o scss/src/block_locator.py scss/src/build.py scss/src/scanner.c scss/src/scanner.h scss/src/scanner.o scss/src/scanner.py scss/src/utils.h scss/src/grammar/LICENSE scss/src/grammar/README scss/src/grammar/grammar.g scss/src/grammar/grammar.py scss/src/grammar/yapps2.py scss/src/grammar/yappsrt.pypyScss-1.1.5/pyScss.egg-info/top_level.txt0000644000076500000240000000000512107522130021151 0ustar kronuzstaff00000000000000scss pyScss-1.1.5/README.rst0000644000076500000240000002731112107521201015137 0ustar kronuzstaff00000000000000pyScss, a Scss compiler for Python ================================== :Author: German M. Bravo (Kronuz) About ===== pyScss compiles Scss (Sass), a superset of CSS that is more powerful, elegant and easier to maintain than plain-vanilla CSS. The library acts as a CSS source code preprocesor which allows you to use variables, nested rules, mixins, and have inheritance of rules, all with a CSS-compatible syntax which the preprocessor then compiles to standard CSS. Scss, as an extension of CSS, helps keep large stylesheets well-organized. It borrows concepts and functionality from projects such as OOCSS and other similar frameworks like as Sass. It's build on top of the original PHP xCSS codebase structure but it's been completely rewritten, many bugs have been fixed and it has been extensively extended to support almost the full range of Sass' Scss syntax and functionality. .. image:: http://pledgie.com/campaigns/16513.png?skin_name=chrome :alt: Click here to lend your support to pyScss and make a donation at pledgie.com! :target: http://pledgie.com/campaigns/16513 Support ======== pyScss is fully compatible with SCSS (Sass) 3.2 ...it has: * **Compass**: Compass 0.11 Support * **Nested rules** * **Keyword arguments** * **Mixins**: `@mixin`, `@include` * **Functions**: `@function`, `@return` * **Inheritance**: `@extend` * **Conditions**: `@if`, `@else if`, `@else` * **Loops**: `@for`, `@each` * **Variables**: `$`, `@variables`, `@vars` * **Sprites**: `sprite-map()`, `sprite()`, `sprite-position()`, `sprite-url()`, ... * **Images**: `image-url()`, `image-width()`, `image-height()`, ... * **Embedded (inline) images**: `inline-image()` * **Colors handling**: `adjust-color()`, `scale-color()`, `opacify()`/`transparentize()`, `lighten()`/`darken()`, `mix()`, ... * **Math functions**: `sin()`, `cos()`, `tan()`, `round()`, `ceil()`, `floor()`, `pi()`, ... * **CSS Compression**: `@option compress:yes;` Requirements ============ * python >= 2.5 Installation ============ pyScss should be installed using pip or setuptools:: pip install pyScss easy_install pyScss Usage ===== Usage example:: from scss import Scss css = Scss() css.compile("a { color: red + green; }") Or compile from the command line:: python -mscss < file.scss Interactive mode:: python -mscss --interactive .. note:: ``-mscss`` will only work in Python 2.7 and above, for Python 2.5 and 2.6 you need to invoke:: python -mscss.tool Examples ======== #. **Nested Rules** Example:: @option compress: no; .selector { a { display: block; } strong { color: blue; } } ...produces:: .selector a { display: block; } .selector strong { color: #00f; } #. **Variables** Example:: @option compress: no; $main-color: #ce4dd6; $style: solid; $side: bottom; #navbar { border-#{$side}: { color: $main-color; style: $style; } } ...produces:: #navbar { border-bottom-color: #ce4dd6; border-bottom-style: solid; } #. **Mixins** Example:: @option compress: no; @mixin rounded($side, $radius: 10px) { border-#{$side}-radius: $radius; -moz-border-radius-#{$side}: $radius; -webkit-border-#{$side}-radius: $radius; } #navbar li { @include rounded(top); } #footer { @include rounded(top, 5px); } #sidebar { @include rounded(left, 8px); } ...produces:: #navbar li { border-top-radius: 10px; -moz-border-radius-top: 10px; -webkit-border-top-radius: 10px; } #footer { border-top-radius: 5px; -moz-border-radius-top: 5px; -webkit-border-top-radius: 5px; } #sidebar { border-left-radius: 8px; -moz-border-radius-left: 8px; -webkit-border-left-radius: 8px; } #. **Extend** (using `@extend`) Example:: @option compress: no; .error { border: 1px #f00; background-color: #fdd; } .error.intrusion { background-image: url("/image/hacked.png"); } .seriousError { @extend .error; border-width: 3px; } ...produces:: .error, .seriousError { border: 1px red; background-color: #fdd; } .error.intrusion, .seriousError.intrusion { background-image: url("/image/hacked.png"); } .seriousError { border-width: 3px; } #. **Sprites** (using `sprite-map()`) Example:: @option compress: no; $icons: sprite-map("sociable/*.png"); // contains sociable/facebook.png among others. div { background: $icons; } @each $icon in sprites($icons) { div .#{$icon} { width: image-width(sprite-file($icons, $icon)); height: image-height(sprite-file($icons, $icon)); background-position: sprite-position($icons, $icon); } } ...generates a new sprite file and produces something like:: div { background: url("/static/assets/u8Y7yEQL0UffAVw5rX7yhw.png?_=1298240989") 0px 0px no-repeat; } div .facebook { width: 32px; height: 32px; background-position: 0px 0px; } div .twitter { width: 32px; height: 32px; background-position: 0px -32px; } ... #. **Interactive mode** Example:: $ python scss.py --interactive >>> @import "compass/css3" >>> show() ['functions', 'mixins', 'options', 'vars'] >>> show(mixins) ['apply-origin', 'apply-transform', ... 'transparent'] >>> show(mixins, transparent) @mixin transparent() { @include opacity(0); } >>> 1px + 5px 6px >>> _ Sass Sassy CSS ============== pyScss is a Scss (Sass) implementation for Python. Currently it implements @mixin, @include, @if, @else, @for, and @import... it also implements many of the Sass functions including color functions like hsla(), hsl(), darken(), lighten(), mix(), opacify(), transparentize(), saturate(), desaturate(), etc.) as well as sprite-map(), sprite-file(), image-width(), image-height() and the others. In the file `scss.py`, by the top, you can configure the LOAD_PATHS to point to your Sass frameworks path (I have `sass/frameworks/compass/*.scss` and `sass/framework/blueprint/*.scss` files in my project directory: `/usr/local/www/project/`, where `scss.py` lives, so it defaults to use the `sass/framework/` path, relative to the `scss.py` file) or configure using the command line `--load-path` option, see `python scss.py --help`. I have succesfully compiled some Compass using `python scss.py < myfile.css` the following `myfile.css`:: @option compress: no; $blueprint-grid-columns : 24; $blueprint-grid-width : 30px; $blueprint-grid-margin : 10px; $font-color : #333; @import "compass/reset"; @import "compass/utilities"; @import "blueprint"; // Stuff goes here... Django Example ============== The following shows some code that can be used with django:: import os import fnmatch import scss from django.conf import settings from django.utils.datastructures import SortedDict from django.contrib.staticfiles import finders def finder(glob): """ Finds all files in the django finders for a given glob, returns the file path, if available, and the django storage object. storage objects must implement the File storage API: https://docs.djangoproject.com/en/dev/ref/files/storage/ """ for finder in finders.get_finders(): for path, storage in finder.list([]): if fnmatch.fnmatchcase(path, glob): yield path, storage # STATIC_ROOT is where pyScss looks for images and static data. # STATIC_ROOT can be either a fully qualified path name or a "finder" # iterable function that receives a filename or glob and returns a tuple # of the file found and its file storage object for each matching file. # (https://docs.djangoproject.com/en/dev/ref/files/storage/) scss.STATIC_ROOT = finder scss.STATIC_URL = settings.STATIC_URL # ASSETS_ROOT is where the pyScss outputs the generated files such as spritemaps # and compile cache: scss.ASSETS_ROOT = os.path.join(settings.MEDIA_ROOT, 'assets/') scss.ASSETS_URL = settings.MEDIA_URL + 'assets/' # These are the paths pyScss will look ".scss" files on. This can be the path to # the compass framework or blueprint or compass-recepies, etc. scss.LOAD_PATHS = [ '/usr/local/www/sass/frameworks/', '/Library/Ruby/Gems/1.8/gems/compass-0.11.5/frameworks/compass/stylesheets/', '/Library/Ruby/Gems/1.8/gems/compass-0.11.5/frameworks/blueprint/stylesheets/', ] # This creates the Scss object used to compile SCSS code. In this example, # _scss_vars will hold the context variables: _scss_vars = {} _scss = scss.Scss( scss_vars=_scss_vars, scss_opts={ 'compress': True, 'debug_info': True, } ) # 1. Compile from a string: compiled_css_from_string = _scss.compile('@import "file2"; a {color: red + green; }') # 2. Compile from a file: compiled_css_from_file = _scss.compile(scss_file='file1.scss') # 3. Compile from a set of files (use SortedDict or collections.OrderedDict to # maintain the compile order): _scss._scss_files = SortedDict(( ('file2.scss', open('file2.scss').read()), ('file3.scss', open('file3.scss').read()), ('file4.scss', open('file4.scss').read()), )) compiled_css_from_files = _scss.compile() Bug tracker =========== If you have any suggestions, bug reports or annoyances please report them to the issue tracker at http://github.com/Kronuz/pyScss/issues Changelog ========= 1.1.5 Feb 15, 2013 + ``debug_info`` now properly produces rules that can be used by FireSass and Google Chrome SASS Source Maps. + Improved memory usage for large sets of files to be used as sprites. + Warns about IE 4095 maximum number of selectors. + ``debug_info`` prints info as comments if specified as ``comments``. + Better handling of undefined variables. + Added CSS filter functions and ``skewX`` ``skewY``. + Command line tool and entry point fixed. + Fix cache buster URLs when paths already include queries or fragments. + Hashable Values. 1.1.4 Aug 8, 2012 + Added ``--debug-info`` command line option (for *FireSass* output). + Added compass helper function ``reject()``. + Added ``undefined`` keyword for undefined variables. 1.1.3 Jan 9, 2012 + Support for the new Sass 3.2.0 features (``@content`` and placeholder selectors) + Fixed bug with line numbers throwing an exception. 1.1.2 Jan 3, 2012 + Regression bug fixed from 1.1.1 1.1.1 Jan 2, 2012 + Added optional C speedup module for an amazing boost in scanning speed! + Added ``headings``, ``stylesheet-url``, ``font-url``, ``font-files``, ``inline-font-files`` and ``sprite-names``. 1.1.0 - Dec 22, 2011 + Added ``min()`` and ``max()`` for lists. + Removed exception raise. 1.0.9 - Dec 22, 2011 + Optimizations in the scanner. + Added ``background-noise()`` for compass-recipes support. + ``enumerate()`` and ``range()`` can go backwards. Ex.: ``range(3, 0)`` goes from 3 to 0. + Added line numbers and files for errors. + Added support for *Firebug* with *FireSass*. + ``nth(n)`` is round (returns the ``nth mod len`` item of the list). + ``--watch`` added to the command line. + Several bugs fixed. 1.0.8 - May 13, 2011 + Changed source color (``$src-color``) default to black. + Moved the module filename to ``__init__.py`` and module renamed back to scss. Contributing ============ Development of pyScss happens at github: https://github.com/Kronuz/pyScss License ======= MIT License. See *LICENSE* for details. http://www.opensource.org/licenses/mit-license.php Copyright ========= Copyright (c) 2012 German M. Bravo (Kronuz) *Bits of code in pyScss come from various projects:* Compass: (c) 2009 Christopher M. Eppstein http://compass-style.org/ Sass: (c) 2006-2009 Hampton Catlin and Nathan Weizenbaum http://sass-lang.com/ xCSS: (c) 2010 Anton Pawlik http://xcss.antpaw.org/docs/ pyScss-1.1.5/scss/0000755000076500000240000000000012107522130014421 5ustar kronuzstaff00000000000000pyScss-1.1.5/scss/.DS_Store0000644000076500000240000003000412104570565016115 0ustar kronuzstaff00000000000000Bud1 spblob®bp  @€ @€ @€ @srcbwspblob®bplist00Ö \WindowBounds[ShowSidebar]ShowStatusBar[ShowPathbar[ShowToolbar\SidebarWidth_{{20, -1}, {1214, 778}} À".? UwidthYascendingWversionK ÔCDE UwidthYascendingXcomments ÔIJKL UwidthYascending^dateLastOpenedÈÔPQR UwidthYascendingYdateAdded ##@(##@0 2DX`r{˜¡´¶·¸ÃÌ×Ýçïô÷øù')*+4:DPQR[akprst}ƒ’”•–Ÿ¥¯µ·¸¹ÂÈÒÚÜÝÞçí÷ *,-.7=GQRS\enwZxsrclsvpblob>bplist00Ú WXYZ _viewOptionsVersion_showIconPreview_calculateAllSizesWcolumns_scrollPositionYXtextSize_scrollPositionXZsortColumnXiconSize_useRelativeDates Ù!(/6=DKRXcomments^dateLastOpened[dateCreatedTsizeUlabelTkindWversionTname\dateModifiedÔ UindexUwidthYascendingWvisible, Ô"#$% UwidthYascendingÈÔ)*+, UwidthYascendingµÔ0123 UwidthYascendinga Ô789: UwidthYascendingd Ô>?@A UwidthYascendings ÔEFGH UwidthYascendingK ÔLMNO UwidthYascendingWvisible ÔST , UwidthYascending ##@(##@0 2DX`r{˜¡´¶·¸ËÔãïôúÿ "(.8@BEFGPV`bdefouƒ„…Ž”ž ¢£¤­³½¿ÁÂÃÌÒÜÞàáâëñûýÿ "$%&/5?@AJS\e\fsrcvSrnlong E DSDB `€ @€ @€ @useRelativeDates Ù!(/6=DKRXcomments^dateLastOpened[dateCreatedTsizeUlabelTkindWversionTname\dateModifiedÔ UindexUwidthYascendingWvisible, Ô"#$% UwidthYascendingÈÔ)*+, UwidthYascendingµÔ0123 UwidthYascendinga Ô789: UwidthYascendingd Ô>?@A UwidthYascendings ÔEFGH UwidthYascendingK ÔLMNO UwidthYascendingWvisible ÔST , UwidthYascending ##@(##@0 2DX`r{˜¡´¶·¸ËÔãïôúÿ "(.8@BEFGPV`bdefouƒ„…Ž”ž ¢£¤­³½¿ÁÂÃÌÒÜÞàáâëñûýÿ "$%&/5?@AJS\e\fsrcvSrnlongpyScss-1.1.5/scss/__init__.py0000644000076500000240000062556612107520276016567 0ustar kronuzstaff00000000000000#!/usr/bin/env python #-*- coding: utf-8 -*- """ pyScss, a Scss compiler for Python @author German M. Bravo (Kronuz) @version 1.1.5 @see https://github.com/Kronuz/pyScss @copyright (c) 2012-2013 German M. Bravo (Kronuz) @license MIT License http://www.opensource.org/licenses/mit-license.php pyScss compiles Scss, a superset of CSS that is more powerful, elegant and easier to maintain than plain-vanilla CSS. The library acts as a CSS source code preprocesor which allows you to use variables, nested rules, mixins, andhave inheritance of rules, all with a CSS-compatible syntax which the preprocessor then compiles to standard CSS. Scss, as an extension of CSS, helps keep large stylesheets well-organized. It borrows concepts and functionality from projects such as OOCSS and other similar frameworks like as Sass. It's build on top of the original PHP xCSS codebase structure but it's been completely rewritten, many bugs have been fixed and it has been extensively extended to support almost the full range of Sass' Scss syntax and functionality. Bits of code in pyScss come from various projects: Compass: (c) 2009 Christopher M. Eppstein http://compass-style.org/ Sass: (c) 2006-2009 Hampton Catlin and Nathan Weizenbaum http://sass-lang.com/ xCSS: (c) 2010 Anton Pawlik http://xcss.antpaw.org/docs/ """ import config from scss_meta import BUILD_INFO, PROJECT, VERSION, REVISION, URL, AUTHOR, AUTHOR_EMAIL, LICENSE __project__ = PROJECT __version__ = VERSION __author__ = AUTHOR + ' <' + AUTHOR_EMAIL + '>' __license__ = LICENSE import os import logging log = logging.getLogger(__name__) try: import cPickle as pickle except ImportError: import pickle import re import sys import time import tempfile import textwrap from collections import deque try: from cStringIO import StringIO except: from StringIO import StringIO ################################################################################ # Load C acceleration modules locate_blocks = None Scanner = None try: from _speedups import locate_blocks, Scanner, NoMoreTokens except ImportError: print >>sys.stderr, "Scanning acceleration disabled (_speedups not found)!" pass ################################################################################ profiling = {} # units and conversions _units = ['em', 'ex', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'deg', 'rad' 'grad', 'ms', 's', 'hz', 'khz', '%'] _zero_units = ['em', 'ex', 'px', 'cm', 'mm', 'in', 'pt', 'pc'] # units that can be zeroed _units_weights = { 'em': 10, 'mm': 10, 'ms': 10, 'hz': 10, '%': 100, } _conv = { 'size': { 'em': 13.0, 'px': 1.0 }, 'length': { 'mm': 1.0, 'cm': 10.0, 'in': 25.4, 'pt': 25.4 / 72, 'pc': 25.4 / 6 }, 'time': { 'ms': 1.0, 's': 1000.0 }, 'freq': { 'hz': 1.0, 'khz': 1000.0 }, 'any': { '%': 1.0 / 100 } } _conv_type = {} _conv_factor = {} for t, m in _conv.items(): for k, f in m.items(): _conv_type[k] = t _conv_factor[k] = f del t, m, k, f # color literals _colors = { 'aliceblue': '#f0f8ff', 'antiquewhite': '#faebd7', 'aqua': '#00ffff', 'aquamarine': '#7fffd4', 'azure': '#f0ffff', 'beige': '#f5f5dc', 'bisque': '#ffe4c4', 'black': '#000000', 'blanchedalmond': '#ffebcd', 'blue': '#0000ff', 'blueviolet': '#8a2be2', 'brown': '#a52a2a', 'burlywood': '#deb887', 'cadetblue': '#5f9ea0', 'chartreuse': '#7fff00', 'chocolate': '#d2691e', 'coral': '#ff7f50', 'cornflowerblue': '#6495ed', 'cornsilk': '#fff8dc', 'crimson': '#dc143c', 'cyan': '#00ffff', 'darkblue': '#00008b', 'darkcyan': '#008b8b', 'darkgoldenrod': '#b8860b', 'darkgray': '#a9a9a9', 'darkgreen': '#006400', 'darkkhaki': '#bdb76b', 'darkmagenta': '#8b008b', 'darkolivegreen': '#556b2f', 'darkorange': '#ff8c00', 'darkorchid': '#9932cc', 'darkred': '#8b0000', 'darksalmon': '#e9967a', 'darkseagreen': '#8fbc8f', 'darkslateblue': '#483d8b', 'darkslategray': '#2f4f4f', 'darkturquoise': '#00ced1', 'darkviolet': '#9400d3', 'deeppink': '#ff1493', 'deepskyblue': '#00bfff', 'dimgray': '#696969', 'dodgerblue': '#1e90ff', 'firebrick': '#b22222', 'floralwhite': '#fffaf0', 'forestgreen': '#228b22', 'fuchsia': '#ff00ff', 'gainsboro': '#dcdcdc', 'ghostwhite': '#f8f8ff', 'gold': '#ffd700', 'goldenrod': '#daa520', 'gray': '#808080', 'green': '#008000', 'greenyellow': '#adff2f', 'honeydew': '#f0fff0', 'hotpink': '#ff69b4', 'indianred': '#cd5c5c', 'indigo': '#4b0082', 'ivory': '#fffff0', 'khaki': '#f0e68c', 'lavender': '#e6e6fa', 'lavenderblush': '#fff0f5', 'lawngreen': '#7cfc00', 'lemonchiffon': '#fffacd', 'lightblue': '#add8e6', 'lightcoral': '#f08080', 'lightcyan': '#e0ffff', 'lightgoldenrodyellow': '#fafad2', 'lightgreen': '#90ee90', 'lightgrey': '#d3d3d3', 'lightpink': '#ffb6c1', 'lightsalmon': '#ffa07a', 'lightseagreen': '#20b2aa', 'lightskyblue': '#87cefa', 'lightslategray': '#778899', 'lightsteelblue': '#b0c4de', 'lightyellow': '#ffffe0', 'lime': '#00ff00', 'limegreen': '#32cd32', 'linen': '#faf0e6', 'magenta': '#ff00ff', 'maroon': '#800000', 'mediumaquamarine': '#66cdaa', 'mediumblue': '#0000cd', 'mediumorchid': '#ba55d3', 'mediumpurple': '#9370db', 'mediumseagreen': '#3cb371', 'mediumslateblue': '#7b68ee', 'mediumspringgreen': '#00fa9a', 'mediumturquoise': '#48d1cc', 'mediumvioletred': '#c71585', 'midnightblue': '#191970', 'mintcream': '#f5fffa', 'mistyrose': '#ffe4e1', 'moccasin': '#ffe4b5', 'navajowhite': '#ffdead', 'navy': '#000080', 'oldlace': '#fdf5e6', 'olive': '#808000', 'olivedrab': '#6b8e23', 'orange': '#ffa500', 'orangered': '#ff4500', 'orchid': '#da70d6', 'palegoldenrod': '#eee8aa', 'palegreen': '#98fb98', 'paleturquoise': '#afeeee', 'palevioletred': '#db7093', 'papayawhip': '#ffefd5', 'peachpuff': '#ffdab9', 'peru': '#cd853f', 'pink': '#ffc0cb', 'plum': '#dda0dd', 'powderblue': '#b0e0e6', 'purple': '#800080', 'red': '#ff0000', 'rosybrown': '#bc8f8f', 'royalblue': '#4169e1', 'saddlebrown': '#8b4513', 'salmon': '#fa8072', 'sandybrown': '#f4a460', 'seagreen': '#2e8b57', 'seashell': '#fff5ee', 'sienna': '#a0522d', 'silver': '#c0c0c0', 'skyblue': '#87ceeb', 'slateblue': '#6a5acd', 'slategray': '#708090', 'snow': '#fffafa', 'springgreen': '#00ff7f', 'steelblue': '#4682b4', 'tan': '#d2b48c', 'teal': '#008080', 'thistle': '#d8bfd8', 'tomato': '#ff6347', 'turquoise': '#40e0d0', 'violet': '#ee82ee', 'wheat': '#f5deb3', 'white': '#ffffff', 'whitesmoke': '#f5f5f5', 'yellow': '#ffff00', 'yellowgreen': '#9acd32' } _safe_strings = { '^doubleslash^': '//', '^bigcopen^': '/*', '^bigcclose^': '*/', '^doubledot^': ':', '^semicolon^': ';', '^curlybracketopen^': '{', '^curlybracketclosed^': '}', } _reverse_safe_strings = dict((v, k) for k, v in _safe_strings.items()) _safe_strings_re = re.compile('|'.join(map(re.escape, _safe_strings))) _reverse_safe_strings_re = re.compile('|'.join(map(re.escape, _reverse_safe_strings))) _default_scss_files = {} # Files to be compiled ({file: content, ...}) _default_scss_index = {0: ':0'} _default_scss_vars = { '$BUILD_INFO': BUILD_INFO, '$PROJECT': PROJECT, '$VERSION': VERSION, '$REVISION': REVISION, '$URL': URL, '$AUTHOR': AUTHOR, '$AUTHOR_EMAIL': AUTHOR_EMAIL, '$LICENSE': LICENSE, # unsafe chars will be hidden as vars '$__doubleslash': '//', '$__bigcopen': '/*', '$__bigcclose': '*/', '$__doubledot': ':', '$__semicolon': ';', '$__curlybracketopen': '{', '$__curlybracketclosed': '}', # shortcuts (it's "a hidden feature" for now) 'bg:': 'background:', 'bgc:': 'background-color:', } _default_scss_opts = { 'verbosity': config.VERBOSITY, 'compress': 1, 'compress_short_colors': 1, # Converts things like #RRGGBB to #RGB 'compress_reverse_colors': 1, # Gets the shortest name of all for colors 'short_colors': 0, # Converts things like #RRGGBB to #RGB 'reverse_colors': 0, # Gets the shortest name of all for colors } SEPARATOR = '\x00' _nl_re = re.compile(r'[ \t\r\f\v]*\n[ \t\r\f\v]*', re.MULTILINE) _nl_num_re = re.compile(r'\n.+' + SEPARATOR, re.MULTILINE) _nl_num_nl_re = re.compile(r'\n.+' + SEPARATOR + r'[ \t\r\f\v]*\n', re.MULTILINE) _short_color_re = re.compile(r'(?'} rule[LINENO] = 0 rule[FINAL] = False else: rule = list(rule) for k, v in kwargs.items(): rule[RULE_VARS[k.upper()]] = v return rule def print_timing(level=0): def _print_timing(func): if config.VERBOSITY: def wrapper(*args, **kwargs): if config.VERBOSITY >= level: t1 = time.time() res = func(*args, **kwargs) t2 = time.time() profiling.setdefault(func.func_name, 0) profiling[func.func_name] += (t2 - t1) return res else: return func(*args, **kwargs) return wrapper else: return func return _print_timing # Profiler decorator # import pstats # import cProfile # def profile(fn): # def wrapper(*args, **kwargs): # profiler = cProfile.Profile() # stream = StringIO() # profiler.enable() # try: # res = fn(*args, **kwargs) # finally: # profiler.disable() # stats = pstats.Stats(profiler, stream=stream) # stats.sort_stats('time') # print >>stream, "" # print >>stream, "=" * 100 # print >>stream, "Stats:" # stats.print_stats() # print >>stream, "=" * 100 # print >>stream, "Callers:" # stats.print_callers() # print >>stream, "=" * 100 # print >>stream, "Callees:" # stats.print_callees() # print >>sys.stderr, stream.getvalue() # stream.close() # return res # return wrapper def split_params(params): params = params.split(',') or [] if params: final_params = [] param = params.pop(0) try: while True: while param.count('(') != param.count(')'): try: param = param + ',' + params.pop(0) except IndexError: break final_params.append(param) param = params.pop(0) except IndexError: pass params = final_params return params def dequote(s): if s and s[0] in ('"', "'") and s[-1] == s[0]: s = s[1:-1] s = unescape(s) return s def depar(s): while s and s[0] == '(' and s[-1] == ')': s = s[1:-1] return s ################################################################################ # Scanner if locate_blocks is None: def _strip_selprop(selprop, lineno): # Get the line number of the selector or property and strip all other # line numbers that might still be there (from multiline selectors) _lineno, _sep, selprop = selprop.partition(SEPARATOR) if _sep == SEPARATOR: _lineno = _lineno.strip(' \t\n;') try: lineno = int(_lineno) except ValueError: pass else: selprop = _lineno selprop = _nl_num_re.sub('\n', selprop) selprop = selprop.strip() return selprop, lineno def _strip(selprop): # Strip all line numbers, ignoring them in the way selprop, _ = _strip_selprop(selprop, None) return selprop def locate_blocks(codestr): """ For processing CSS like strings. Either returns all selectors (that can be "smart" multi-lined, as long as it's joined by `,`, or enclosed in `(` and `)`) with its code block (the one between `{` and `}`, which can be nested), or the "lose" code (properties) that doesn't have any blocks. threshold is the number of blank lines before selectors are broken into pieces (properties). """ lineno = 0 par = 0 instr = None depth = 0 skip = False thin = None i = init = safe = lose = 0 start = end = None for m in _blocks_re.finditer(codestr): i = m.start(0) c = codestr[i] if instr is not None: if c == instr: instr = None # A string ends (FIXME: needs to accept escaped characters) elif c in ('"', "'"): instr = c # A string starts elif c == '(': # parenthesis begins: par += 1 thin = None safe = i + 1 elif c == ')': # parenthesis ends: par -= 1 elif not par and not instr: if c == '{': # block begins: if depth == 0: if i > 0 and codestr[i - 1] == '#': # Do not process #{...} as blocks! skip = True else: start = i if thin is not None and _strip(codestr[thin:i]): init = thin if lose < init: _property, lineno = _strip_selprop(codestr[lose:init], lineno) if _property: yield lineno, _property, None lose = init thin = None depth += 1 elif c == '}': # block ends: if depth > 0: depth -= 1 if depth == 0: if not skip: end = i _selectors, lineno = _strip_selprop(codestr[init:start], lineno) _codestr = codestr[start + 1:end].strip() if _selectors: yield lineno, _selectors, _codestr init = safe = lose = end + 1 thin = None skip = False elif depth == 0: if c == ';': # End of property (or block): init = i if lose < init: _property, lineno = _strip_selprop(codestr[lose:init], lineno) if _property: yield lineno, _property, None init = safe = lose = i + 1 thin = None elif c == ',': if thin is not None and _strip(codestr[thin:i]): init = thin thin = None safe = i + 1 elif c == '\n': if thin is not None and _strip(codestr[thin:i]): init = thin thin = i + 1 elif thin is None and _strip(codestr[safe:i]): thin = i + 1 # Step on thin ice, if it breaks, it breaks here if depth > 0: if not skip: _selectors, lineno = _strip_selprop(codestr[init:start], lineno) _codestr = codestr[start + 1:].strip() if _selectors: yield lineno, _selectors, _codestr if par: raise Exception("Missing closing parenthesis somewhere in block: '%s'" % _selectors) elif instr: raise Exception("Missing closing string somewhere in block: '%s'" % _selectors) else: raise Exception("Block never closed: '%s'" % _selectors) losestr = codestr[lose:] for _property in losestr.split(';'): _property, lineno = _strip_selprop(_property, lineno) if _property: yield lineno, _property, None ################################################################################ class Scss(object): # configuration: construct = 'self' def __init__(self, scss_vars=None, scss_opts=None, scss_files=None, super_selector=None): if super_selector: self.super_selector = super_selector + ' ' else: self.super_selector = '' self._scss_vars = scss_vars self._scss_opts = scss_opts self._scss_files = scss_files self.reset() def get_scss_constants(self): scss_vars = self.scss_vars or {} return dict((k, v) for k, v in scss_vars.items() if k and (not k.startswith('$') or k.startswith('$') and k[1].isupper())) def get_scss_vars(self): scss_vars = self.scss_vars or {} return dict((k, v) for k, v in scss_vars.items() if k and not (not k.startswith('$') or k.startswith('$') and k[1].isupper())) def clean(self): self.children = deque() self.rules = [] self._rules = {} self.parts = {} def reset(self, input_scss=None): if hasattr(CalculatorScanner, 'cleanup'): CalculatorScanner.cleanup() # Initialize self.css_files = [] self.scss_vars = _default_scss_vars.copy() if self._scss_vars is not None: self.scss_vars.update(self._scss_vars) self.scss_opts = _default_scss_opts.copy() if self._scss_opts is not None: self.scss_opts.update(self._scss_opts) self.scss_files = {} self._scss_files_order = [] for f, c in _default_scss_files.iteritems(): if f not in self.scss_files: self._scss_files_order.append(f) self.scss_files[f] = c if self._scss_files is not None: for f, c in self._scss_files.iteritems(): if f not in self.scss_files: self._scss_files_order.append(f) self.scss_files[f] = c self._scss_index = _default_scss_index.copy() self._contexts = {} self.clean() #@profile #@print_timing(2) def Compilation(self, scss_string=None, scss_file=None, super_selector=None, filename=None): if super_selector: self.super_selector = super_selector + ' ' if scss_string is not None: self._scss_files = {filename or '' % (scss_string.strip()[:50] + '...'): scss_string} elif scss_file is not None: self._scss_files = {filename or scss_file: open(scss_file).read()} self.reset() # Compile for fileid in self._scss_files_order: codestr = self.scss_files[fileid] codestr = self.load_string(codestr, fileid) self.scss_files[fileid] = codestr rule = spawn_rule(fileid=fileid, codestr=codestr, context=self.scss_vars, options=self.scss_opts, index=self._scss_index) self.children.append(rule) # this will manage rule: child objects inside of a node self.parse_children() # this will manage rule: ' extends ' self.parse_extends() # this will manage the order of the rules self.manage_order() self.parse_properties() all_rules = 0 all_selectors = 0 exceeded = '' final_cont = '' for fileid in self.css_files: fcont, total_rules, total_selectors = self.create_css(fileid) all_rules += total_rules all_selectors += total_selectors if not exceeded and all_selectors > 4095: exceeded = " (IE exceeded!)" log.error("Maximum number of supported selectors in Internet Explorer (4095) exceeded!") if self.scss_opts.get('debug_info', False): if fileid.startswith('>sys.stderr, '='*80 #for r in [rule]+list(self.children)[:5]: print >>sys.stderr, repr(r[POSITION]), repr(r[SELECTORS]), repr(r[CODESTR][:80]+('...' if len(r[CODESTR])>80 else '')) #for r in [rule]+list(self.children)[:5]: print >>sys.stderr, repr(r[POSITION]), repr(r[SELECTORS]), repr(r[CODESTR][:80]+('...' if len(r[CODESTR])>80 else '')), dict((k, v) for k, v in r[CONTEXT].items() if k.startswith('$') and not k.startswith('$__')), dict(r[PROPERTIES]).keys() @print_timing(4) def manage_children(self, rule, p_selectors, p_parents, p_children, scope, media): for c_lineno, c_property, c_codestr in locate_blocks(rule[CODESTR]): if '@return' in rule[OPTIONS]: return # Rules preprocessing... if c_property.startswith('+'): # expands a '+' at the beginning of a rule as @include c_property = '@include ' + c_property[1:] try: if '(' not in c_property or c_property.index(':') < c_property.index('('): c_property = c_property.replace(':', '(', 1) if '(' in c_property: c_property += ')' except ValueError: pass elif c_property.startswith('='): # expands a '=' at the beginning of a rule as @mixin c_property = '@mixin' + c_property[1:] elif c_property == '@prototype ': # Remove '@prototype ' c_property = c_property[11:] #################################################################### if c_property.startswith('@'): code, name = (c_property.split(None, 1) + [''])[:2] code = code.lower() if code == '@warn': name = self.calculate(name, rule[CONTEXT], rule[OPTIONS], rule) log.warn(dequote(to_str(name))) elif code == '@print': name = self.calculate(name, rule[CONTEXT], rule[OPTIONS], rule) print >>sys.stderr, dequote(to_str(name)) elif code == '@raw': name = self.calculate(name, rule[CONTEXT], rule[OPTIONS], rule) print >>sys.stderr, repr(name) elif code == '@dump_context': log.info(repr(rule[CONTEXT])) elif code == '@dump_options': log.info(repr(rule[OPTIONS])) elif code == '@debug': name = name.strip() if name.lower() in ('1', 'true', 't', 'yes', 'y', 'on'): name = 1 elif name.lower() in ('0', 'false', 'f', 'no', 'n', 'off', 'undefined'): name = 0 config.DEBUG = name log.info("Debug mode is %s", 'On' if config.DEBUG else 'Off') elif code == '@option': self._settle_options(rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name) elif code == '@content': self._do_content(rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name) elif code == '@import': self._do_import(rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name) elif code == '@extend': name = self.apply_vars(name, rule[CONTEXT], rule[OPTIONS], rule) p_parents.update(p.strip() for p in name.replace(',', '&').split('&')) p_parents.discard('') elif c_codestr is not None and code in ('@mixin', '@function'): self._do_functions(rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name) elif code == '@return': ret = self.calculate(name, rule[CONTEXT], rule[OPTIONS], rule) rule[OPTIONS]['@return'] = ret elif code == '@include': self._do_include(rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name) elif c_codestr is not None and (code == '@if' or c_property.startswith('@else if ')): self._do_if(rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name) elif c_codestr is not None and code == '@else': self._do_else(rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name) elif c_codestr is not None and code == '@for': self._do_for(rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name) elif c_codestr is not None and code == '@each': self._do_each(rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name) # elif c_codestr is not None and code == '@while': # self._do_while(rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name) elif c_codestr is not None and code in ('@variables', '@vars'): self._get_variables(rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr) elif c_codestr is not None and code == '@media': _media = (media or []) + [name] rule[CODESTR] = self.construct + ' {' + c_codestr + '}' self.manage_children(rule, p_selectors, p_parents, p_children, scope, _media) elif c_codestr is None: rule[PROPERTIES].append((c_lineno, c_property, None)) elif scope is None: # needs to have no scope to crawl down the nested rules self._nest_rules(rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr) #################################################################### # Properties elif c_codestr is None: self._get_properties(rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr) # Nested properties elif c_property.endswith(':'): rule[CODESTR] = c_codestr self.manage_children(rule, p_selectors, p_parents, p_children, (scope or '') + c_property[:-1] + '-', media) #################################################################### # Nested rules elif scope is None: # needs to have no scope to crawl down the nested rules self._nest_rules(rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr) @print_timing(10) def _settle_options(self, rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name): for option in name.split(','): option, value = (option.split(':', 1) + [''])[:2] option = option.strip().lower() value = value.strip() if option: if value.lower() in ('1', 'true', 't', 'yes', 'y', 'on'): value = 1 elif value.lower() in ('0', 'false', 'f', 'no', 'n', 'off', 'undefined'): value = 0 rule[OPTIONS][option] = value @print_timing(10) def _do_functions(self, rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name): """ Implements @mixin and @function """ if not name: return funct, params, _ = name.partition('(') funct = funct.strip() params = split_params(depar(params + _)) defaults = {} new_params = [] for param in params: param, _, default = param.partition(':') param = param.strip() default = default.strip() if param: new_params.append(param) if default: default = self.apply_vars(default, rule[CONTEXT], None, rule) defaults[param] = default context = rule[CONTEXT].copy() for p in new_params: context.pop(p, None) mixin = [list(new_params), defaults, self.apply_vars(c_codestr, context, None, rule)] if code == '@function': def _call(mixin): def __call(R, *args, **kwargs): m_params = mixin[0] m_vars = rule[CONTEXT].copy() m_vars.update(mixin[1]) m_codestr = mixin[2] for i, a in enumerate(args): m_vars[m_params[i]] = a m_vars.update(kwargs) _options = rule[OPTIONS].copy() _rule = spawn_rule(R, codestr=m_codestr, context=m_vars, options=_options, deps=set(), properties=[], final=False, lineno=c_lineno) self.manage_children(_rule, p_selectors, p_parents, p_children, (scope or '') + '', R[MEDIA]) ret = _rule[OPTIONS].pop('@return', '') return ret return __call _mixin = _call(mixin) _mixin.mixin = mixin mixin = _mixin # Insert as many @mixin options as the default parameters: while len(new_params): rule[OPTIONS]['%s %s:%d' % (code, funct, len(new_params))] = mixin param = new_params.pop() if param not in defaults: break if not new_params: rule[OPTIONS][code + ' ' + funct + ':0'] = mixin @print_timing(10) def _do_include(self, rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name): """ Implements @include, for @mixins """ funct, params, _ = name.partition('(') funct = funct.strip() funct = self.do_glob_math(funct, rule[CONTEXT], rule[OPTIONS], rule, True) params = split_params(depar(params + _)) new_params = {} num_args = 0 for param in params: varname, _, param = param.partition(':') if param: param = param.strip() varname = varname.strip() else: param = varname.strip() varname = num_args if param: num_args += 1 if param: new_params[varname] = param mixin = rule[OPTIONS].get('@mixin %s:%s' % (funct, num_args)) if not mixin: # Fallback to single parmeter: mixin = rule[OPTIONS].get('@mixin %s:1' % (funct,)) if mixin and all(map(lambda o: isinstance(o, int), new_params.keys())): new_params = {0: ', '.join(new_params.values())} if not mixin: log.error("Required mixin not found: %s:%d (%s)", funct, num_args, rule[INDEX][rule[LINENO]], extra={'stack': True}) return m_params = mixin[0] m_vars = mixin[1].copy() m_codestr = mixin[2] for varname, value in new_params.items(): try: m_param = m_params[varname] except: m_param = varname value = self.calculate(value, rule[CONTEXT], rule[OPTIONS], rule) m_vars[m_param] = value for p in m_params: if p not in new_params: if isinstance(m_vars[p], basestring): value = self.calculate(m_vars[p], m_vars, rule[OPTIONS], rule) m_vars[p] = value _context = rule[CONTEXT].copy() _context.update(m_vars) _rule = spawn_rule(rule, codestr=m_codestr, context=_context, lineno=c_lineno) _rule[OPTIONS]['@content'] = c_codestr self.manage_children(_rule, p_selectors, p_parents, p_children, scope, media) @print_timing(10) def _do_content(self, rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name): """ Implements @content """ if '@content' not in rule[OPTIONS]: log.error("Content string not found for @content (%s)", rule[INDEX][rule[LINENO]]) c_codestr = rule[OPTIONS].pop('@content', '') rule[CODESTR] = c_codestr self.manage_children(rule, p_selectors, p_parents, p_children, scope, media) @print_timing(10) def _do_import(self, rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name): """ Implements @import Load and import mixins and functions and rules """ # Protect against going to prohibited places... if '..' in name or '://' in name or 'url(' in name: rule[PROPERTIES].append((c_lineno, c_property, None)) return full_filename = None i_codestr = None names = name.split(',') for name in names: name = dequote(name.strip()) if '@import ' + name in rule[OPTIONS]: # If already imported in this scope, skip continue unsupported = [] load_paths = [] filename = os.path.basename(name) dirname = os.path.dirname(name) try: i_codestr = self.scss_files[name] except KeyError: i_codestr = None # TODO: Convert global config.LOAD_PATHS to a list. Use it directly. # Doing the above will break backwards compatibility! if hasattr(config.LOAD_PATHS, 'split'): load_path_list = config.LOAD_PATHS.split(',') # Old style else: load_path_list = config.LOAD_PATHS # New style load_path_list.extend(self._scss_opts['load_paths'] if self._scss_opts and 'load_paths' in self._scss_opts else []) for path in ['./'] + load_path_list: for basepath in ['./', os.path.dirname(rule[PATH])]: i_codestr = None full_path = os.path.realpath(os.path.join(path, basepath, dirname)) if full_path in load_paths: continue try: full_filename = os.path.join(full_path, '_' + filename) i_codestr = open(full_filename + '.scss').read() full_filename += '.scss' except IOError: if os.path.exists(full_filename + '.sass'): unsupported.append(full_filename + '.sass') try: full_filename = os.path.join(full_path, filename) i_codestr = open(full_filename + '.scss').read() full_filename += '.scss' except IOError: if os.path.exists(full_filename + '.sass'): unsupported.append(full_filename + '.sass') try: full_filename = os.path.join(full_path, '_' + filename) i_codestr = open(full_filename).read() except IOError: try: full_filename = os.path.join(full_path, filename) i_codestr = open(full_filename).read() except IOError: pass if i_codestr is not None: break else: load_paths.append(full_path) if i_codestr is not None: break if i_codestr is None: i_codestr = self._do_magic_import(rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name) i_codestr = self.scss_files[name] = i_codestr and self.load_string(i_codestr, full_filename) if name not in self.scss_files: self._scss_files_order.append(name) if i_codestr is None: load_paths = load_paths and "\nLoad paths:\n\t%s" % "\n\t".join(load_paths) or '' unsupported = unsupported and "\nPossible matches (for unsupported file format SASS):\n\t%s" % "\n\t".join(unsupported) or '' log.warn("File to import not found or unreadable: '%s' (%s)%s%s", filename, rule[INDEX][rule[LINENO]], load_paths, unsupported) else: _rule = spawn_rule(rule, codestr=i_codestr, path=full_filename, lineno=c_lineno) self.manage_children(_rule, p_selectors, p_parents, p_children, scope, media) rule[OPTIONS]['@import ' + name] = True @print_timing(10) def _do_magic_import(self, rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name): """ Implements @import for sprite-maps Imports magic sprite map directories """ if callable(config.STATIC_ROOT): files = sorted(config.STATIC_ROOT(name)) else: glob_path = os.path.join(config.STATIC_ROOT, name) files = glob.glob(glob_path) files = sorted((file[len(config.STATIC_ROOT):], None) for file in files) if not files: return # Build magic context map_name = os.path.normpath(os.path.dirname(name)).replace('\\', '_').replace('/', '_') kwargs = {} def setdefault(var, val): _var = '$' + map_name + '-' + var if _var in rule[CONTEXT]: kwargs[var] = interpolate(rule[CONTEXT][_var], rule) else: rule[CONTEXT][_var] = val kwargs[var] = interpolate(val, rule) return rule[CONTEXT][_var] setdefault('sprite-base-class', StringValue('.' + map_name + '-sprite')) setdefault('sprite-dimensions', BooleanValue(False)) position = setdefault('position', NumberValue(0, '%')) spacing = setdefault('spacing', NumberValue(0)) repeat = setdefault('repeat', StringValue('no-repeat')) names = tuple(os.path.splitext(os.path.basename(file))[0] for file, storage in files) for n in names: setdefault(n + '-position', position) setdefault(n + '-spacing', spacing) setdefault(n + '-repeat', repeat) sprite_map = _sprite_map(name, **kwargs) rule[CONTEXT]['$' + map_name + '-' + 'sprites'] = sprite_map ret = ''' @import "compass/utilities/sprites/base"; // All sprites should extend this class // The %(map_name)s-sprite mixin will do so for you. #{$%(map_name)s-sprite-base-class} { background: $%(map_name)s-sprites; } // Use this to set the dimensions of an element // based on the size of the original image. @mixin %(map_name)s-sprite-dimensions($name) { @include sprite-dimensions($%(map_name)s-sprites, $name); } // Move the background position to display the sprite. @mixin %(map_name)s-sprite-position($name, $offset-x: 0, $offset-y: 0) { @include sprite-position($%(map_name)s-sprites, $name, $offset-x, $offset-y); } // Extends the sprite base class and set the background position for the desired sprite. // It will also apply the image dimensions if $dimensions is true. @mixin %(map_name)s-sprite($name, $dimensions: $%(map_name)s-sprite-dimensions, $offset-x: 0, $offset-y: 0) { @extend #{$%(map_name)s-sprite-base-class}; @include sprite($%(map_name)s-sprites, $name, $dimensions, $offset-x, $offset-y); } @mixin %(map_name)s-sprites($sprite-names, $dimensions: $%(map_name)s-sprite-dimensions) { @include sprites($%(map_name)s-sprites, $sprite-names, $%(map_name)s-sprite-base-class, $dimensions); } // Generates a class for each sprited image. @mixin all-%(map_name)s-sprites($dimensions: $%(map_name)s-sprite-dimensions) { @include %(map_name)s-sprites(%(sprites)s, $dimensions); } ''' % {'map_name': map_name, 'sprites': ' '.join(names)} return ret @print_timing(10) def _do_if(self, rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name): """ Implements @if and @else if """ if code != '@if': if '@if' not in rule[OPTIONS]: log.error("@else with no @if (%s)", rule[INDEX][rule[LINENO]]) val = not rule[OPTIONS].get('@if', True) name = c_property[9:].strip() else: val = True if val: val = self.calculate(name, rule[CONTEXT], rule[OPTIONS], rule) val = bool(False if not val or isinstance(val, basestring) and (val in ('0', 'false', 'undefined') or _variable_re.match(val)) else val) if val: rule[CODESTR] = c_codestr self.manage_children(rule, p_selectors, p_parents, p_children, scope, media) rule[OPTIONS]['@if'] = val @print_timing(10) def _do_else(self, rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name): """ Implements @else """ if '@if' not in rule[OPTIONS]: log.error("@else with no @if (%s)", rule[INDEX][rule[LINENO]]) val = rule[OPTIONS].pop('@if', True) if not val: rule[CODESTR] = c_codestr self.manage_children(rule, p_selectors, p_parents, p_children, scope, media) @print_timing(10) def _do_for(self, rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name): """ Implements @for """ var, _, name = name.partition(' from ') frm, _, through = name.partition(' through ') if not through: frm, _, through = frm.partition(' to ') frm = self.calculate(frm, rule[CONTEXT], rule[OPTIONS], rule) through = self.calculate(through, rule[CONTEXT], rule[OPTIONS], rule) try: frm = int(float(frm)) through = int(float(through)) except ValueError: return if frm > through: frm, through = through, frm rev = reversed else: rev = lambda x: x var = var.strip() var = self.do_glob_math(var, rule[CONTEXT], rule[OPTIONS], rule, True) for i in rev(range(frm, through + 1)): rule[CODESTR] = c_codestr rule[CONTEXT][var] = str(i) self.manage_children(rule, p_selectors, p_parents, p_children, scope, media) @print_timing(10) def _do_each(self, rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name): """ Implements @each """ var, _, name = name.partition(' in ') name = self.calculate(name, rule[CONTEXT], rule[OPTIONS], rule) if not name: return name = ListValue(name) var = var.strip() var = self.do_glob_math(var, rule[CONTEXT], rule[OPTIONS], rule, True) for n, v in name.items(): v = to_str(v) rule[CODESTR] = c_codestr rule[CONTEXT][var] = v if not isinstance(n, int): rule[CONTEXT][n] = v self.manage_children(rule, p_selectors, p_parents, p_children, scope, media) # @print_timing(10) # def _do_while(self, rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name): # THIS DOES NOT WORK AS MODIFICATION OF INNER VARIABLES ARE NOT KNOWN AT THIS POINT!! # """ # Implements @while # """ # first_val = None # while True: # val = self.calculate(name, rule[CONTEXT], rule[OPTIONS], rule) # val = bool(False if not val or isinstance(val, basestring) and (val in ('0', 'false', 'undefined') or _variable_re.match(val)) else val) # if first_val is None: # first_val = val # if not val: # break # rule[CODESTR] = c_codestr # self.manage_children(rule, p_selectors, p_parents, p_children, scope, media) # rule[OPTIONS]['@if'] = first_val @print_timing(10) def _get_variables(self, rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr): """ Implements @variables and @vars """ _rule = list(rule) _rule[CODESTR] = c_codestr _rule[PROPERTIES] = rule[CONTEXT] self.manage_children(_rule, p_selectors, p_parents, p_children, scope, media) @print_timing(10) def _get_properties(self, rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr): """ Implements properties and variables extraction and assignment """ prop, value = (_prop_split_re.split(c_property, 1) + [None])[:2] try: is_var = (c_property[len(prop)] == '=') except IndexError: is_var = False prop = prop.strip() prop = self.do_glob_math(prop, rule[CONTEXT], rule[OPTIONS], rule, True) if not prop: return if value: value = value.strip() value = self.calculate(value, rule[CONTEXT], rule[OPTIONS], rule) _prop = (scope or '') + prop if is_var or prop.startswith('$') and value is not None: in_context = rule[CONTEXT].get(_prop) is_defined = not (in_context is None or isinstance(in_context, basestring) and _undefined_re.match(in_context)) if isinstance(value, basestring): if '!default' in value: if is_defined: value = None if value is not None: value = value.replace('!default', '').replace(' ', ' ').strip() if value is not None and prop.startswith('$') and prop[1].isupper(): if is_defined: log.warn("Constant %r redefined", prop) elif isinstance(value, ListValue): value = ListValue(value) for k, v in value.value.items(): if v == '!default': if is_defined: value = None if value is not None: del value.value[k] value = value.first() if len(value) == 1 else value break if value is not None: rule[CONTEXT][_prop] = value else: _prop = self.apply_vars(_prop, rule[CONTEXT], rule[OPTIONS], rule, True) rule[PROPERTIES].append((c_lineno, _prop, to_str(value) if value is not None else None)) @print_timing(10) def _nest_rules(self, rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr): """ Implements Nested CSS rules """ if c_property == self.construct and rule[MEDIA] == media: rule[CODESTR] = c_codestr self.manage_children(rule, p_selectors, p_parents, p_children, scope, media) return c_property = self.apply_vars(c_property, rule[CONTEXT], rule[OPTIONS], rule, True) c_selectors = self.normalize_selectors(c_property) c_selectors, _, c_parents = c_selectors.partition(' extends ') better_selectors = set() c_selectors = c_selectors.split(',') for c_selector in c_selectors: for p_selector in p_selectors: if c_selector == self.construct: better_selectors.add(p_selector) elif '&' in c_selector: # Parent References better_selectors.add(c_selector.replace('&', p_selector)) elif p_selector: better_selectors.add(p_selector + ' ' + c_selector) else: better_selectors.add(c_selector) better_selectors = ','.join(sorted(better_selectors)) if c_parents: parents = set(p.strip() for p in c_parents.split('&')) parents.discard('') if parents: better_selectors += ' extends ' + '&'.join(sorted(parents)) _rule = spawn_rule(rule, codestr=c_codestr, deps=set(), context=rule[CONTEXT].copy(), options=rule[OPTIONS].copy(), selectors=better_selectors, properties=[], final=False, media=media, lineno=c_lineno) p_children.appendleft(_rule) @print_timing(4) def link_with_parents(self, parent, c_selectors, c_rules): """ Link with a parent for the current child rule. If parents found, returns a list of parent rules to the child """ parent_found = None for p_selectors, p_rules in self.parts.items(): _p_selectors, _, _ = p_selectors.partition(' extends ') _p_selectors = _p_selectors.split(',') new_selectors = set() found = False # Finds all the parent selectors and parent selectors with another # bind selectors behind. For example, if `.specialClass extends .baseClass`, # and there is a `.baseClass` selector, the extension should create # `.specialClass` for that rule, but if there's also a `.baseClass a` # it also should create `.specialClass a` for p_selector in _p_selectors: if parent not in p_selector: continue # get the new child selector to add (same as the parent selector but with the child name) # since selectors can be together, separated with # or . (i.e. something.parent) check that too: for c_selector in c_selectors.split(','): # Get whatever is different between the two selectors: _c_selector, _parent = c_selector, parent lcp = self.longest_common_prefix(_c_selector, _parent) if lcp: _c_selector = _c_selector[lcp:] _parent = _parent[lcp:] lcs = self.longest_common_suffix(_c_selector, _parent) if lcs: _c_selector = _c_selector[:-lcs] _parent = _parent[:-lcs] if _c_selector and _parent: # Get the new selectors: prev_symbol = '(?>sys.stderr, rule[FILEID], rule[POSITION], [ c for c in rule[CONTEXT] if c[1] != '_' ], rule[OPTIONS].keys(), rule[SELECTORS], rule[DEPS] if rule[POSITION] is not None and rule[PROPERTIES]: fileid = rule[FILEID] self._rules.setdefault(fileid, []) self._rules[fileid].append(rule) if old_fileid != fileid: old_fileid = fileid if fileid not in css_files: css_files.add(fileid) self.css_files.append(fileid) @print_timing(3) def create_css(self, fileid=None): """ Generate the final CSS string """ if fileid: rules = self._rules.get(fileid) or [] else: rules = self.rules compress = self.scss_opts.get('compress', True) if compress: sc, sp, tb, nl = False, '', '', '' else: sc, sp, tb, nl = True, ' ', ' ', '\n' scope = set() return self._create_css(rules, scope, sc, sp, tb, nl, not compress and self.scss_opts.get('debug_info', False)) def _create_css(self, rules, scope=None, sc=True, sp=' ', tb=' ', nl='\n', debug_info=False): if scope is None: scope = set() open_selectors = False skip_selectors = False old_selectors = None open_media = False old_media = None old_property = None wrap = textwrap.TextWrapper(break_long_words=False, break_on_hyphens=False) wrap.wordsep_re = re.compile(r'(?<=,)(\s*)') wrap = wrap.wrap total_rules = 0 total_selectors = 0 result = '' for rule in rules: #print >>sys.stderr, rule[FILEID], rule[MEDIA], rule[POSITION], [ c for c in rule[CONTEXT] if not c.startswith('$__') ], rule[OPTIONS].keys(), rule[SELECTORS], rule[DEPS] if rule[POSITION] is None or not rule[PROPERTIES]: continue selectors = rule[SELECTORS] media = rule[MEDIA] _tb = tb if old_media else '' if old_media != media or media is not None: if open_selectors: if not skip_selectors: if not sc and result[-1] == ';': result = result[:-1] result += _tb + '}' + nl open_selectors = False skip_selectors = False if open_media: if not sc and result[-1] == ';': result = result[:-1] result += '}' + nl open_media = False if media: result += '@media ' + (' and ').join(set(media)) + sp + '{' + nl open_media = True old_media = media old_selectors = None # force entrance to add a new selector _tb = tb if media else '' if old_selectors != selectors or selectors is not None: if open_selectors: if not skip_selectors: if not sc and result[-1] == ';': result = result[:-1] result += _tb + '}' + nl open_selectors = False skip_selectors = False if selectors: _selectors = [s for s in selectors.split(',') if '%' not in s] if _selectors: total_rules += 1 total_selectors += len(_selectors) if debug_info: _lineno = rule[LINENO] line = rule[INDEX][_lineno] filename, lineno = line.rsplit(':', 1) real_filename, real_lineno = filename, lineno # Walk up to a non-library file: # while _lineno >= 0: # path, name = os.path.split(line) # if not name.startswith('_'): # filename, lineno = line.rsplit(':', 1) # break # line = rule[INDEX][_lineno] # _lineno -= 1 sass_debug_info = '' if filename.startswith(' 1: result += _tb + '/* file: ' + rule[FILEID] + ' */' + nl if rule[CONTEXT]: result += _tb + '/* vars:' + nl for k, v in rule[CONTEXT].items(): result += _tb + _tb + k + ' = ' + v + ';' + nl result += _tb + '*/' + nl if not skip_selectors: result += self._print_properties(rule[PROPERTIES], scope, [old_property], sc, sp, _tb, nl, wrap) if open_media: _tb = tb else: _tb = '' if open_selectors and not skip_selectors: if not sc and result[-1] == ';': result = result[:-1] result += _tb + '}' + nl if open_media: if not sc and result[-1] == ';': result = result[:-1] result += '}' + nl return (result, total_rules, total_selectors) def _print_properties(self, properties, scope=None, old_property=None, sc=True, sp=' ', _tb='', nl='\n', wrap=None): if wrap is None: wrap = textwrap.TextWrapper(break_long_words=False) wrap.wordsep_re = re.compile(r'(?<=,)(\s*)') wrap = wrap.wrap if old_property is None: old_property = [None] if scope is None: scope = set() result = '' for lineno, prop, value in properties: if value is not None: if nl: value = (nl + _tb + _tb).join(wrap(value)) property = prop + ':' + sp + value else: property = prop if '!default' in property: property = property.replace('!default', '').replace(' ', ' ').strip() if prop in scope: continue if old_property[0] != property: old_property[0] = property scope.add(prop) old_property[0] = property result += _tb + property + ';' + nl return result def calculate(self, _base_str, context, options, rule): better_expr_str = _base_str if _skip_word_re.match(better_expr_str) and '- ' not in better_expr_str and ' and ' not in better_expr_str and ' or ' not in better_expr_str and 'not ' not in better_expr_str: return better_expr_str rule = list(rule) rule[CONTEXT] = context rule[OPTIONS] = options better_expr_str = self.do_glob_math(better_expr_str, context, options, rule) better_expr_str = eval_expr(better_expr_str, rule, True) if better_expr_str is None: better_expr_str = self.apply_vars(_base_str, context, options, rule) return better_expr_str def _calculate_expr(self, context, options, rule, _dequote): def __calculate_expr(result): _group0 = result.group(1) _base_str = _group0 better_expr_str = eval_expr(_base_str, rule) if better_expr_str is None: better_expr_str = self.apply_vars(_base_str, context, options, rule) elif _dequote: better_expr_str = dequote(str(better_expr_str)) else: better_expr_str = str(better_expr_str) return better_expr_str return __calculate_expr def do_glob_math(self, cont, context, options, rule, _dequote=False): cont = str(cont) if '#{' not in cont: return cont cont = _expr_glob_re.sub(self._calculate_expr(context, options, rule, _dequote), cont) return cont @print_timing(3) def post_process(self, cont): compress = self.scss_opts.get('compress', 1) and 'compress_' or '' # short colors: if self.scss_opts.get(compress + 'short_colors', 1): cont = _short_color_re.sub(r'#\1\2\3', cont) # color names: if self.scss_opts.get(compress + 'reverse_colors', 1): cont = _reverse_colors_re.sub(lambda m: _reverse_colors[m.group(0).lower()], cont) if compress: # zero units out (i.e. 0px or 0em -> 0): cont = _zero_units_re.sub('0', cont) # remove zeros before decimal point (i.e. 0.3 -> .3) cont = _zero_re.sub('.', cont) return cont import random import hashlib import base64 import datetime import mimetypes import glob import math import operator import colorsys try: from PIL import Image, ImageDraw except ImportError: try: import Image, ImageDraw except: Image = None ################################################################################ def to_str(num): if isinstance(num, dict): s = sorted(num.items()) sp = num.get('_', '') return (sp + ' ').join(to_str(v) for n, v in s if n != '_') elif isinstance(num, float): num = ('%0.03f' % round(num, 3)).rstrip('0').rstrip('.') return num elif isinstance(num, bool): return 'true' if num else 'false' elif num is None: return '' return str(num) def to_float(num): if isinstance(num, (float, int)): return float(num) num = to_str(num) if num and num[-1] == '%': return float(num[:-1]) / 100.0 else: return float(num) hex2rgba = { 9: lambda c: (int(c[1:3], 16), int(c[3:5], 16), int(c[5:7], 16), int(c[7:9], 16)), 7: lambda c: (int(c[1:3], 16), int(c[3:5], 16), int(c[5:7], 16), 1.0), 5: lambda c: (int(c[1] * 2, 16), int(c[2] * 2, 16), int(c[3] * 2, 16), int(c[4] * 2, 16)), 4: lambda c: (int(c[1] * 2, 16), int(c[2] * 2, 16), int(c[3] * 2, 16), 1.0), } def escape(s): return re.sub(r'''(["'])''', r'\\\1', s) def unescape(s): return re.sub(r'''\\(['"])''', r'\1', s) ################################################################################ # Sass/Compass Library Functions: def _rgb(r, g, b, type='rgb'): return _rgba(r, g, b, 1.0, type) def _rgba(r, g, b, a, type='rgba'): c = NumberValue(r), NumberValue(g), NumberValue(b), NumberValue(a) col = [c[i].value * 255.0 if (c[i].unit == '%' or c[i].value > 0 and c[i].value <= 1) else 0.0 if c[i].value < 0 else 255.0 if c[i].value > 255 else c[i].value for i in range(3) ] col += [0.0 if c[3].value < 0 else 1.0 if c[3].value > 1 else c[3].value] col += [type] return ColorValue(col) def _color_type(color, a, type): color = ColorValue(color).value a = NumberValue(a).value if a is not None else color[3] col = list(color[:3]) col += [0.0 if a < 0 else 1.0 if a > 1 else a] col += [type] return ColorValue(col) def _rgb2(color): return _color_type(color, 1.0, 'rgb') def _rgba2(color, a=None): return _color_type(color, a, 'rgba') def _hsl2(color): return _color_type(color, 1.0, 'hsl') def _hsla2(color, a=None): return _color_type(color, a, 'hsla') def _ie_hex_str(color): c = ColorValue(color).value return StringValue('#%02X%02X%02X%02X' % (round(c[3] * 255), round(c[0]), round(c[1]), round(c[2]))) def _hsl(h, s, l, type='hsl'): return _hsla(h, s, l, 1.0, type) def _hsla(h, s, l, a, type='hsla'): c = NumberValue(h), NumberValue(s), NumberValue(l), NumberValue(a) col = [c[0] if (c[0].unit == '%' and c[0].value > 0 and c[0].value <= 1) else (c[0].value % 360.0) / 360.0] col += [0.0 if cl <= 0 else 1.0 if cl >= 1.0 else cl for cl in [ c[i].value if (c[i].unit == '%' or c[i].value > 0 and c[i].value <= 1) else c[i].value / 100.0 for i in range(1, 4) ] ] col += [type] c = [c * 255.0 for c in colorsys.hls_to_rgb(col[0], 0.999999 if col[2] == 1 else col[2], 0.999999 if col[1] == 1 else col[1])] + [col[3], type] col = ColorValue(c) return col def __rgba_op(op, color, r, g, b, a): color = ColorValue(color) c = color.value a = [ None if r is None else NumberValue(r).value, None if g is None else NumberValue(g).value, None if b is None else NumberValue(b).value, None if a is None else NumberValue(a).value, ] # Do the additions: c = [op(c[i], a[i]) if op is not None and a[i] is not None else a[i] if a[i] is not None else c[i] for i in range(4)] # Validations: r = 255.0, 255.0, 255.0, 1.0 c = [0.0 if c[i] < 0 else r[i] if c[i] > r[i] else c[i] for i in range(4)] color.value = tuple(c) return color def _opacify(color, amount): return __rgba_op(operator.__add__, color, 0, 0, 0, amount) def _transparentize(color, amount): return __rgba_op(operator.__sub__, color, 0, 0, 0, amount) def __hsl_op(op, color, h, s, l): color = ColorValue(color) c = color.value h = None if h is None else NumberValue(h) s = None if s is None else NumberValue(s) l = None if l is None else NumberValue(l) a = [ None if h is None else h.value / 360.0, None if s is None else s.value / 100.0 if s.unit != '%' and s.value >= 1 else s.value, None if l is None else l.value / 100.0 if l.unit != '%' and l.value >= 1 else l.value, ] # Convert to HSL: h, l, s = list(colorsys.rgb_to_hls(c[0] / 255.0, c[1] / 255.0, c[2] / 255.0)) c = h, s, l # Do the additions: c = [0.0 if c[i] < 0 else 1.0 if c[i] > 1 else op(c[i], a[i]) if op is not None and a[i] is not None else a[i] if a[i] is not None else c[i] for i in range(3)] # Validations: c[0] = (c[0] * 360.0) % 360 r = 360.0, 1.0, 1.0 c = [0.0 if c[i] < 0 else r[i] if c[i] > r[i] else c[i] for i in range(3)] # Convert back to RGB: c = colorsys.hls_to_rgb(c[0] / 360.0, 0.999999 if c[2] == 1 else c[2], 0.999999 if c[1] == 1 else c[1]) color.value = (c[0] * 255.0, c[1] * 255.0, c[2] * 255.0, color.value[3]) return color def _lighten(color, amount): return __hsl_op(operator.__add__, color, 0, 0, amount) def _darken(color, amount): return __hsl_op(operator.__sub__, color, 0, 0, amount) def _saturate(color, amount): return __hsl_op(operator.__add__, color, 0, amount, 0) def _desaturate(color, amount): return __hsl_op(operator.__sub__, color, 0, amount, 0) def _grayscale(color): return __hsl_op(operator.__sub__, color, 0, 100.0, 0) def _adjust_hue(color, degrees): return __hsl_op(operator.__add__, color, degrees, 0, 0) def _complement(color): return __hsl_op(operator.__add__, color, 180.0, 0, 0) def _invert(color): """ Returns the inverse (negative) of a color. The red, green, and blue values are inverted, while the opacity is left alone. """ col = ColorValue(color) c = col.value c[0] = 255.0 - c[0] c[1] = 255.0 - c[1] c[2] = 255.0 - c[2] return col def _adjust_lightness(color, amount): return __hsl_op(operator.__add__, color, 0, 0, amount) def _adjust_saturation(color, amount): return __hsl_op(operator.__add__, color, 0, amount, 0) def _scale_lightness(color, amount): return __hsl_op(operator.__mul__, color, 0, 0, amount) def _scale_saturation(color, amount): return __hsl_op(operator.__mul__, color, 0, amount, 0) def _asc_color(op, color, saturation=None, lightness=None, red=None, green=None, blue=None, alpha=None): if lightness or saturation: color = __hsl_op(op, color, 0, saturation, lightness) if red or green or blue or alpha: color = __rgba_op(op, color, red, green, blue, alpha) return color def _adjust_color(color, saturation=None, lightness=None, red=None, green=None, blue=None, alpha=None): return _asc_color(operator.__add__, color, saturation, lightness, red, green, blue, alpha) def _scale_color(color, saturation=None, lightness=None, red=None, green=None, blue=None, alpha=None): return _asc_color(operator.__mul__, color, saturation, lightness, red, green, blue, alpha) def _change_color(color, saturation=None, lightness=None, red=None, green=None, blue=None, alpha=None): return _asc_color(None, color, saturation, lightness, red, green, blue, alpha) def _mix(color1, color2, weight=None): """ Mixes together two colors. Specifically, takes the average of each of the RGB components, optionally weighted by the given percentage. The opacity of the colors is also considered when weighting the components. Specifically, takes the average of each of the RGB components, optionally weighted by the given percentage. The opacity of the colors is also considered when weighting the components. The weight specifies the amount of the first color that should be included in the returned color. 50%, means that half the first color and half the second color should be used. 25% means that a quarter of the first color and three quarters of the second color should be used. For example: mix(#f00, #00f) => #7f007f mix(#f00, #00f, 25%) => #3f00bf mix(rgba(255, 0, 0, 0.5), #00f) => rgba(63, 0, 191, 0.75) """ # This algorithm factors in both the user-provided weight # and the difference between the alpha values of the two colors # to decide how to perform the weighted average of the two RGB values. # # It works by first normalizing both parameters to be within [-1, 1], # where 1 indicates "only use color1", -1 indicates "only use color 0", # and all values in between indicated a proportionately weighted average. # # Once we have the normalized variables w and a, # we apply the formula (w + a)/(1 + w*a) # to get the combined weight (in [-1, 1]) of color1. # This formula has two especially nice properties: # # * When either w or a are -1 or 1, the combined weight is also that number # (cases where w * a == -1 are undefined, and handled as a special case). # # * When a is 0, the combined weight is w, and vice versa # # Finally, the weight of color1 is renormalized to be within [0, 1] # and the weight of color2 is given by 1 minus the weight of color1. # # Algorithm from the Sass project: http://sass-lang.com/ c1 = ColorValue(color1).value c2 = ColorValue(color2).value p = NumberValue(weight).value if weight is not None else 0.5 p = 0.0 if p < 0 else 1.0 if p > 1 else p w = p * 2 - 1 a = c1[3] - c2[3] w1 = ((w if (w * a == -1) else (w + a) / (1 + w * a)) + 1) / 2.0 w2 = 1 - w1 q = [w1, w1, w1, p] r = [w2, w2, w2, 1 - p] color = ColorValue(None).merge(c1).merge(c2) color.value = [c1[i] * q[i] + c2[i] * r[i] for i in range(4)] return color def _red(color): c = ColorValue(color).value return NumberValue(c[0]) def _green(color): c = ColorValue(color).value return NumberValue(c[1]) def _blue(color): c = ColorValue(color).value return NumberValue(c[2]) def _alpha(color): c = ColorValue(color).value return NumberValue(c[3]) def _hue(color): c = ColorValue(color).value h, l, s = colorsys.rgb_to_hls(c[0] / 255.0, c[1] / 255.0, c[2] / 255.0) ret = NumberValue(h * 360.0) ret.units = {'deg': _units_weights.get('deg', 1), '_': 'deg'} return ret def _saturation(color): c = ColorValue(color).value h, l, s = colorsys.rgb_to_hls(c[0] / 255.0, c[1] / 255.0, c[2] / 255.0) ret = NumberValue(s) ret.units = {'%': _units_weights.get('%', 1), '_': '%'} return ret def _lightness(color): c = ColorValue(color).value h, l, s = colorsys.rgb_to_hls(c[0] / 255.0, c[1] / 255.0, c[2] / 255.0) ret = NumberValue(l) ret.units = {'%': _units_weights.get('%', 1), '_': '%'} return ret def __color_stops(percentages, *args): if len(args) == 1: if isinstance(args[0], (list, tuple, ListValue)): return ListValue(args[0]).values() elif isinstance(args[0], (StringValue, basestring)): color_stops = [] colors = split_params(args[0].value) for color in colors: color = color.strip() if color.startswith('color-stop('): s, c = split_params(color[11:].rstrip(')')) s = s.strip() c = c.strip() else: c, s = color.split() color_stops.append((to_float(s), c)) return color_stops colors = [] stops = [] prev_color = False for c in args: if isinstance(c, ListValue): for i, c in c.items(): if isinstance(c, ColorValue): if prev_color: stops.append(None) colors.append(c) prev_color = True elif isinstance(c, NumberValue): stops.append(c) prev_color = False else: if isinstance(c, ColorValue): if prev_color: stops.append(None) colors.append(c) prev_color = True elif isinstance(c, NumberValue): stops.append(NumberValue(c)) prev_color = False if prev_color: stops.append(None) stops = stops[:len(colors)] if percentages: max_stops = max(s and (s.value if s.unit != '%' else None) or None for s in stops) else: max_stops = max(s and (s if s.unit != '%' else None) or None for s in stops) stops = [s and (s.value / max_stops if s.unit != '%' else s.value) for s in stops] stops[0] = 0 init = 0 start = None for i, s in enumerate(stops + [1.0]): if s is None: if start is None: start = i end = i else: final = s if start is not None: stride = (final - init) / (end - start + 1 + (1 if i < len(stops) else 0)) for j in range(start, end + 1): stops[j] = init + stride * (j - start + 1) init = final start = None if not max_stops or percentages: stops = [NumberValue(s, '%') for s in stops] else: stops = [s * max_stops for s in stops] return zip(stops, colors) def _grad_color_stops(*args): if len(args) == 1 and isinstance(args[0], (list, tuple, ListValue)): args = ListValue(args[0]).values() color_stops = __color_stops(True, *args) ret = ', '.join(['color-stop(%s, %s)' % (to_str(s), c) for s, c in color_stops]) return StringValue(ret) def __grad_end_position(radial, color_stops): return __grad_position(-1, 100, radial, color_stops) def __grad_position(index, default, radial, color_stops): try: stops = NumberValue(color_stops[index][0]) if radial and stops.unit != 'px' and (index == 0 or index == -1 or index == len(color_stops) - 1): log.warn("Webkit only supports pixels for the start and end stops for radial gradients. Got %s", stops) except IndexError: stops = NumberValue(default) return stops def _grad_end_position(*color_stops): color_stops = __color_stops(False, *color_stops) return NumberValue(__grad_end_position(False, color_stops)) def _color_stops(*args): if len(args) == 1 and isinstance(args[0], (list, tuple, ListValue)): args = ListValue(args[0]).values() color_stops = __color_stops(False, *args) ret = ', '.join(['%s %s' % (c, to_str(s)) for s, c in color_stops]) return StringValue(ret) def _color_stops_in_percentages(*args): if len(args) == 1 and isinstance(args[0], (list, tuple, ListValue)): args = ListValue(args[0]).values() color_stops = __color_stops(True, *args) ret = ', '.join(['%s %s' % (c, to_str(s)) for s, c in color_stops]) return StringValue(ret) def _get_gradient_position_and_angle(args): for arg in args: if isinstance(arg, (StringValue, NumberValue, basestring)): _arg = [arg] elif isinstance(arg, (list, tuple, ListValue)): _arg = arg else: continue ret = None skip = False for a in _arg: if isinstance(a, ColorValue): skip = True break elif isinstance(a, NumberValue): ret = arg if skip: continue if ret is not None: return ret for seek in ( 'center', 'top', 'bottom', 'left', 'right', ): if seek in _arg: return arg return None def _get_gradient_shape_and_size(args): for arg in args: if isinstance(arg, (StringValue, NumberValue, basestring)): _arg = [arg] elif isinstance(arg, (list, tuple, ListValue)): _arg = arg else: continue for seek in ( 'circle', 'ellipse', 'closest-side', 'closest-corner', 'farthest-side', 'farthest-corner', 'contain', 'cover', ): if seek in _arg: return arg return None def _get_gradient_color_stops(args): color_stops = [] for arg in args: if isinstance(arg, ColorValue): color_stops.append(arg) elif isinstance(arg, (list, tuple, ListValue)): for a in arg: if isinstance(a, ColorValue): color_stops.append(arg) break return color_stops or None def _radial_gradient(*args): if len(args) == 1 and isinstance(args[0], (list, tuple, ListValue)): args = ListValue(args[0]).values() position_and_angle = _get_gradient_position_and_angle(args) shape_and_size = _get_gradient_shape_and_size(args) color_stops = _get_gradient_color_stops(args) color_stops = __color_stops(False, *color_stops) args = [ _position(position_and_angle) if position_and_angle is not None else None, shape_and_size if shape_and_size is not None else None, ] args.extend('%s %s' % (c, to_str(s)) for s, c in color_stops) to__s = 'radial-gradient(' + ', '.join(to_str(a) for a in args or [] if a is not None) + ')' ret = StringValue(to__s) def to__css2(): return StringValue('') ret.to__css2 = to__css2 def to__moz(): return StringValue('-moz-' + to__s) ret.to__moz = to__moz def to__pie(): log.warn("PIE does not support radial-gradient.") return StringValue('-pie-radial-gradient(unsupported)') ret.to__pie = to__pie def to__webkit(): return StringValue('-webkit-' + to__s) ret.to__webkit = to__webkit def to__owg(): args = [ 'radial', _grad_point(position_and_angle) if position_and_angle is not None else 'center', '0', _grad_point(position_and_angle) if position_and_angle is not None else 'center', __grad_end_position(True, color_stops), ] args.extend('color-stop(%s, %s)' % (to_str(s), c) for s, c in color_stops) ret = '-webkit-gradient(' + ', '.join(to_str(a) for a in args or [] if a is not None) + ')' return StringValue(ret) ret.to__owg = to__owg def to__svg(): return _radial_svg_gradient(color_stops, position_and_angle or 'center') ret.to__svg = to__svg return ret def _linear_gradient(*args): if len(args) == 1 and isinstance(args[0], (list, tuple, ListValue)): args = ListValue(args[0]).values() position_and_angle = _get_gradient_position_and_angle(args) color_stops = _get_gradient_color_stops(args) color_stops = __color_stops(False, *color_stops) args = [ _position(position_and_angle) if position_and_angle is not None else None, ] args.extend('%s %s' % (c, to_str(s)) for s, c in color_stops) to__s = 'linear-gradient(' + ', '.join(to_str(a) for a in args or [] if a is not None) + ')' ret = StringValue(to__s) def to__css2(): return StringValue('') ret.to__css2 = to__css2 def to__moz(): return StringValue('-moz-' + to__s) ret.to__moz = to__moz def to__pie(): return StringValue('-pie-' + to__s) ret.to__pie = to__pie def to__ms(): return StringValue('-ms-' + to__s) ret.to__ms = to__ms def to__o(): return StringValue('-o-' + to__s) ret.to__o = to__o def to__webkit(): return StringValue('-webkit-' + to__s) ret.to__webkit = to__webkit def to__owg(): args = [ 'linear', _position(position_and_angle or 'center top'), _opposite_position(position_and_angle or 'center top'), ] args.extend('color-stop(%s, %s)' % (to_str(s), c) for s, c in color_stops) ret = '-webkit-gradient(' + ', '.join(to_str(a) for a in args or [] if a is not None) + ')' return StringValue(ret) ret.to__owg = to__owg def to__svg(): return _linear_svg_gradient(color_stops, position_and_angle or 'top') ret.to__svg = to__svg return ret def _radial_svg_gradient(*args): if len(args) == 1 and isinstance(args[0], (list, tuple, ListValue)): args = ListValue(args[0]).values() color_stops = args center = None if isinstance(args[-1], (StringValue, NumberValue, basestring)): center = args[-1] color_stops = args[:-1] color_stops = __color_stops(False, *color_stops) cx, cy = zip(*_grad_point(center).items())[1] r = __grad_end_position(True, color_stops) svg = __radial_svg(color_stops, cx, cy, r) url = 'data:' + 'image/svg+xml' + ';base64,' + base64.b64encode(svg) inline = 'url("%s")' % escape(url) return StringValue(inline) def _linear_svg_gradient(*args): if len(args) == 1 and isinstance(args[0], (list, tuple, ListValue)): args = ListValue(args[0]).values() color_stops = args start = None if isinstance(args[-1], (StringValue, NumberValue, basestring)): start = args[-1] color_stops = args[:-1] color_stops = __color_stops(False, *color_stops) x1, y1 = zip(*_grad_point(start).items())[1] x2, y2 = zip(*_grad_point(_opposite_position(start)).items())[1] svg = __linear_svg(color_stops, x1, y1, x2, y2) url = 'data:' + 'image/svg+xml' + ';base64,' + base64.b64encode(svg) inline = 'url("%s")' % escape(url) return StringValue(inline) def __color_stops_svg(color_stops): ret = ''.join('' % (to_str(s), c) for s, c in color_stops) return ret def __svg_template(gradient): ret = '\ \ %s\ \ ' % gradient return ret def __linear_svg(color_stops, x1, y1, x2, y2): gradient = '%s' % ( to_str(NumberValue(x1)), to_str(NumberValue(y1)), to_str(NumberValue(x2)), to_str(NumberValue(y2)), __color_stops_svg(color_stops) ) return __svg_template(gradient) def __radial_svg(color_stops, cx, cy, r): gradient = '%s' % ( to_str(NumberValue(cx)), to_str(NumberValue(cy)), to_str(NumberValue(r)), __color_stops_svg(color_stops) ) return __svg_template(gradient) ################################################################################ # Compass like functionality for sprites and images: sprite_maps = {} sprite_images = {} def _sprite_map(g, **kwargs): """ Generates a sprite map from the files matching the glob pattern. Uses the keyword-style arguments passed in to control the placement. """ g = StringValue(g).value if not Image: raise Exception("Images manipulation require PIL") if g in sprite_maps: sprite_maps[glob]['*'] = datetime.datetime.now() elif '..' not in g: # Protect against going to prohibited places... vertical = (kwargs.get('direction', 'vertical') == 'vertical') repeat = StringValue(kwargs.get('repeat', 'no-repeat')) position = NumberValue(kwargs.get('position', 0)) collapse_x = NumberValue(kwargs.get('collapse_x', 0)) collapse_y = NumberValue(kwargs.get('collapse_y', 0)) if position and position > -1 and position < 1: position.units = {'%': _units_weights.get('%', 1), '_': '%'} dst_colors = kwargs.get('dst_color') if isinstance(dst_colors, ListValue): dst_colors = [list(ColorValue(v).value[:3]) for n, v in dst_colors.items() if v] else: dst_colors = [list(ColorValue(dst_colors).value[:3])] if dst_colors else [] src_colors = kwargs.get('src_color') if isinstance(src_colors, ListValue): src_colors = [tuple(ColorValue(v).value[:3]) if v else (0, 0, 0) for n, v in src_colors.items()] else: src_colors = [tuple(ColorValue(src_colors).value[:3]) if src_colors else (0, 0, 0)] len_colors = max(len(dst_colors), len(src_colors)) dst_colors = (dst_colors * len_colors)[:len_colors] src_colors = (src_colors * len_colors)[:len_colors] spacing = kwargs.get('spacing', 0) if isinstance(spacing, ListValue): spacing = [int(NumberValue(v).value) for n, v in spacing.items()] else: spacing = [int(NumberValue(spacing).value)] spacing = (spacing * 4)[:4] if callable(config.STATIC_ROOT): glob_path = g rfiles = files = sorted(config.STATIC_ROOT(g)) else: glob_path = os.path.join(config.STATIC_ROOT, g) files = glob.glob(glob_path) files = sorted((f, None) for f in files) rfiles = [(f[len(config.STATIC_ROOT):], s) for f, s in files] if not files: log.error("Nothing found at '%s'", glob_path) return StringValue(None) times = [] for file, storage in files: try: d_obj = storage.modified_time(file) times.append(int(time.mktime(d_obj.timetuple()))) except: times.append(int(os.path.getmtime(file))) map_name = os.path.normpath(os.path.dirname(g)).replace('\\', '_').replace('/', '_') key = list(zip(*files)[0]) + times + [repr(kwargs), config.ASSETS_URL] key = map_name + '-' + base64.urlsafe_b64encode(hashlib.md5(repr(key)).digest()).rstrip('=').replace('-', '_') asset_file = key + '.png' asset_path = os.path.join(config.ASSETS_ROOT, asset_file) try: asset, map, sizes = pickle.load(open(asset_path + '.cache')) sprite_maps[asset] = map except: def images(): for file, storage in files: yield Image.open(storage.open(file)) if storage is not None else Image.open(file) names = tuple(os.path.splitext(os.path.basename(file))[0] for file, storage in files) positions = [] spacings = [] tot_spacings = [] for name in names: name = name.replace('-', '_') _position = kwargs.get(name + '_position') if _position is None: _position = position else: _position = NumberValue(_position) if _position and _position > -1 and _position < 1: _position.units = {'%': _units_weights.get('%', 1), '_': '%'} positions.append(_position) _spacing = kwargs.get(name + '_spacing') if _spacing is None: _spacing = spacing else: if isinstance(_spacing, ListValue): _spacing = [int(NumberValue(v).value) for n, v in _spacing.items()] else: _spacing = [int(NumberValue(_spacing).value)] _spacing = (_spacing * 4)[:4] spacings.append(_spacing) if _position and _position.unit != '%': if vertical: if _position > 0: tot_spacings.append((_spacing[0], _spacing[1], _spacing[2], _spacing[3] + _position)) else: if _position > 0: tot_spacings.append((_spacing[0] + _position, _spacing[1], _spacing[2], _spacing[3])) else: tot_spacings.append(_spacing) sizes = tuple((collapse_x or image.size[0], collapse_y or image.size[1]) for image in images()) _spacings = zip(*tot_spacings) if vertical: width = max(zip(*sizes)[0]) + max(_spacings[1]) + max(_spacings[3]) height = sum(zip(*sizes)[1]) + sum(_spacings[0]) + sum(_spacings[2]) else: width = sum(zip(*sizes)[0]) + sum(_spacings[1]) + sum(_spacings[3]) height = max(zip(*sizes)[1]) + max(_spacings[0]) + max(_spacings[2]) new_image = Image.new( mode='RGBA', size=(width, height), color=(0, 0, 0, 0) ) offsets_x = [] offsets_y = [] offset = 0 for i, image in enumerate(images()): spacing = spacings[i] position = positions[i] iwidth, iheight = image.size width, height = sizes[i] if vertical: if position and position.unit == '%': x = width * position.value - (spacing[3] + height + spacing[1]) elif position.value < 0: x = width + position.value - (spacing[3] + height + spacing[1]) else: x = position.value offset += spacing[0] for i, dst_color in enumerate(dst_colors): src_color = src_colors[i] pixdata = image.load() for _y in xrange(image.size[1]): for _x in xrange(image.size[0]): pixel = pixdata[_x, _y] if pixel[:3] == src_color: pixdata[_x, _y] = tuple([int(c) for c in dst_color] + [pixel[3] if len(pixel) == 4 else 255]) if iwidth != width or iheight != height: cy = 0 while cy < iheight: cx = 0 while cx < iwidth: cropped_image = image.crop((cx, cy, cx + width, cy + height)) new_image.paste(cropped_image, (int(x + spacing[3]), offset), cropped_image) cx += width cy += height else: new_image.paste(image, (int(x + spacing[3]), offset)) offsets_x.append(x) offsets_y.append(offset - spacing[0]) offset += height + spacing[2] else: if position and position.unit == '%': y = height * position.value - (spacing[0] + height + spacing[2]) elif position.value < 0: y = height + position.value - (spacing[0] + height + spacing[2]) else: y = position.value offset += spacing[3] for i, dst_color in enumerate(dst_colors): src_color = src_colors[i] pixdata = image.load() for _y in xrange(image.size[1]): for _x in xrange(image.size[0]): pixel = pixdata[_x, _y] if pixel[:3] == src_color: pixdata[_x, _y] = tuple([int(c) for c in dst_color] + [pixel[3] if len(pixel) == 4 else 255]) if iwidth != width or iheight != height: cy = 0 while cy < iheight: cx = 0 while cx < iwidth: cropped_image = image.crop((cx, cy, cx + width, cy + height)) new_image.paste(cropped_image, (offset, int(y + spacing[0])), cropped_image) cx += width cy += height else: new_image.paste(image, (offset, int(y + spacing[0]))) offsets_x.append(offset - spacing[3]) offsets_y.append(y) offset += width + spacing[1] try: new_image.save(asset_path) except IOError: log.exception("Error while saving image") filetime = int(time.mktime(datetime.datetime.now().timetuple())) url = '%s%s?_=%s' % (config.ASSETS_URL, asset_file, filetime) asset = 'url("%s") %s' % (escape(url), repeat) # Use the sorted list to remove older elements (keep only 500 objects): if len(sprite_maps) > 1000: for a in sorted(sprite_maps, key=lambda a: sprite_maps[a]['*'], reverse=True)[500:]: del sprite_maps[a] # Add the new object: map = dict(zip(names, zip(sizes, rfiles, offsets_x, offsets_y))) map['*'] = datetime.datetime.now() map['*f*'] = asset_file map['*k*'] = key map['*n*'] = map_name map['*t*'] = filetime tmp_dir = config.ASSETS_ROOT cache_tmp = tempfile.NamedTemporaryFile(delete=False, dir=tmp_dir) pickle.dump((asset, map, zip(files, sizes)), cache_tmp) cache_tmp.close() os.rename(cache_tmp.name, asset_path + '.cache') sprite_maps[asset] = map for file, size in sizes: sprite_images[file] = size ret = StringValue(asset) return ret def _grid_image(left_gutter, width, right_gutter, height, columns=1, grid_color=None, baseline_color=None, background_color=None, inline=False): if not Image: raise Exception("Images manipulation require PIL") if grid_color == None: grid_color = (120, 170, 250, 15) else: c = ColorValue(grid_color).value grid_color = (c[0], c[1], c[2], int(c[3] * 255.0)) if baseline_color == None: baseline_color = (120, 170, 250, 30) else: c = ColorValue(baseline_color).value baseline_color = (c[0], c[1], c[2], int(c[3] * 255.0)) if background_color == None: background_color = (0, 0, 0, 0) else: c = ColorValue(background_color).value background_color = (c[0], c[1], c[2], int(c[3] * 255.0)) _height = int(height) if height >= 1 else int(height * 1000.0) _width = int(width) if width >= 1 else int(width * 1000.0) _left_gutter = int(left_gutter) if left_gutter >= 1 else int(left_gutter * 1000.0) _right_gutter = int(right_gutter) if right_gutter >= 1 else int(right_gutter * 1000.0) if _height <= 0 or _width <= 0 or _left_gutter <= 0 or _right_gutter <= 0: raise ValueError _full_width = (_left_gutter + _width + _right_gutter) new_image = Image.new( mode='RGBA', size=(_full_width * int(columns), _height), color=background_color ) draw = ImageDraw.Draw(new_image) for i in range(int(columns)): draw.rectangle((i * _full_width + _left_gutter, 0, i * _full_width + _left_gutter + _width - 1, _height - 1), fill=grid_color) if _height > 1: draw.rectangle((0, _height - 1, _full_width * int(columns) - 1, _height - 1), fill=baseline_color) if not inline: grid_name = 'grid_' if left_gutter: grid_name += str(int(left_gutter)) + '+' grid_name += str(int(width)) if right_gutter: grid_name += '+' + str(int(right_gutter)) if height and height > 1: grid_name += 'x' + str(int(height)) key = (columns, grid_color, baseline_color, background_color) key = grid_name + '-' + base64.urlsafe_b64encode(hashlib.md5(repr(key)).digest()).rstrip('=').replace('-', '_') asset_file = key + '.png' asset_path = os.path.join(config.ASSETS_ROOT, asset_file) try: new_image.save(asset_path) except IOError: log.exception("Error while saving image") inline = True # Retry inline version url = '%s%s' % (config.ASSETS_URL, asset_file) if inline: output = StringIO() new_image.save(output, format='PNG') contents = output.getvalue() output.close() url = 'data:image/png;base64,' + base64.b64encode(contents) inline = 'url("%s")' % escape(url) return StringValue(inline) def _image_color(color, width=1, height=1): if not Image: raise Exception("Images manipulation require PIL") c = ColorValue(color).value w = int(NumberValue(width).value) h = int(NumberValue(height).value) if w <= 0 or h <= 0: raise ValueError new_image = Image.new( mode='RGB' if c[3] == 1 else 'RGBA', size=(w, h), color=(c[0], c[1], c[2], int(c[3] * 255.0)) ) output = StringIO() new_image.save(output, format='PNG') contents = output.getvalue() output.close() mime_type = 'image/png' url = 'data:' + mime_type + ';base64,' + base64.b64encode(contents) inline = 'url("%s")' % escape(url) return StringValue(inline) def _sprite_map_name(map): """ Returns the name of a sprite map The name is derived from the folder than contains the sprites. """ map = StringValue(map).value sprite_map = sprite_maps.get(map) if not sprite_map: log.error("No sprite map found: %s", map, extra={'stack': True}) if sprite_map: return StringValue(sprite_map['*n*']) return StringValue(None) def _sprite_file(map, sprite): """ Returns the relative path (from the images directory) to the original file used when construction the sprite. This is suitable for passing to the image_width and image_height helpers. """ map = StringValue(map).value sprite_name = StringValue(sprite).value sprite_map = sprite_maps.get(map) sprite = sprite_map and sprite_map.get(sprite_name) if not sprite_map: log.error("No sprite map found: %s", map, extra={'stack': True}) elif not sprite: log.error("No sprite found: %s in %s", sprite_name, sprite_map['*n*'], extra={'stack': True}) if sprite: return QuotedStringValue(sprite[1][0]) return StringValue(None) def _sprites(map): map = StringValue(map).value sprite_map = sprite_maps.get(map, {}) return ListValue(sorted(s for s in sprite_map if not s.startswith('*'))) def _sprite(map, sprite, offset_x=None, offset_y=None): """ Returns the image and background position for use in a single shorthand property """ map = StringValue(map).value sprite_name = StringValue(sprite).value sprite_map = sprite_maps.get(map) sprite = sprite_map and sprite_map.get(sprite_name) if not sprite_map: log.error("No sprite map found: %s", map, extra={'stack': True}) elif not sprite: log.error("No sprite found: %s in %s", sprite_name, sprite_map['*n*'], extra={'stack': True}) if sprite: url = '%s%s?_=%s' % (config.ASSETS_URL, sprite_map['*f*'], sprite_map['*t*']) x = NumberValue(offset_x or 0, 'px') y = NumberValue(offset_y or 0, 'px') if not x or (x <= -1 or x >= 1) and x.unit != '%': x -= sprite[2] if not y or (y <= -1 or y >= 1) and y.unit != '%': y -= sprite[3] pos = "url(%s) %s %s" % (escape(url), x, y) return StringValue(pos) return StringValue('0 0') def _sprite_url(map): """ Returns a url to the sprite image. """ map = StringValue(map).value sprite_map = sprite_maps.get(map) if not sprite_map: log.error("No sprite map found: %s", map, extra={'stack': True}) if sprite_map: url = '%s%s?_=%s' % (config.ASSETS_URL, sprite_map['*f*'], sprite_map['*t*']) url = "url(%s)" % escape(url) return StringValue(url) return StringValue(None) def _sprite_position(map, sprite, offset_x=None, offset_y=None): """ Returns the position for the original image in the sprite. This is suitable for use as a value to background-position. """ map = StringValue(map).value sprite_name = StringValue(sprite).value sprite_map = sprite_maps.get(map) sprite = sprite_map and sprite_map.get(sprite_name) if not sprite_map: log.error("No sprite map found: %s", map, extra={'stack': True}) elif not sprite: log.error("No sprite found: %s in %s", sprite_name, sprite_map['*n*'], extra={'stack': True}) if sprite: x = None if offset_x is not None and not isinstance(offset_x, NumberValue): x = str(offset_x) if x not in ('left', 'right', 'center'): if x: offset_x = None x = NumberValue(offset_x or 0, 'px') if not x or (x <= -1 or x >= 1) and x.unit != '%': x -= sprite[2] y = None if offset_y is not None and not isinstance(offset_y, NumberValue): y = str(offset_y) if y not in ('top', 'bottom', 'center'): if y: offset_y = None y = NumberValue(offset_y or 0, 'px') if not y or (y <= -1 or y >= 1) and y.unit != '%': y -= sprite[3] pos = '%s %s' % (x, y) return StringValue(pos) return StringValue('0 0') def _background_noise(intensity=None, opacity=None, size=None, monochrome=False, inline=False): if not Image: raise Exception("Images manipulation require PIL") intensity = intensity and NumberValue(intensity).value if not intensity or intensity < 0 or intensity > 1: intensity = 0.5 opacity = opacity and NumberValue(opacity).value if not opacity or opacity < 0 or opacity > 1: opacity = 0.08 size = size and int(NumberValue(size).value) if not size or size < 1 or size > 512: size = 200 monochrome = bool(monochrome) new_image = Image.new( mode='RGBA', size=(size, size) ) pixdata = new_image.load() for i in range(0, int(round(intensity * size ** 2))): x = random.randint(1, size) y = random.randint(1, size) r = random.randint(0, 255) a = int(round(random.randint(0, 255) * opacity)) color = (r, r, r, a) if monochrome else (r, random.randint(0, 255), random.randint(0, 255), a) pixdata[x - 1, y - 1] = color if not inline: key = (intensity, opacity, size, monochrome) asset_file = 'noise_%s%sx%s+%s+%s' % ('mono_' if monochrome else '', size, size, to_str(intensity).replace('.', '_'), to_str(opacity).replace('.', '_')) asset_file = asset_file + '-' + base64.urlsafe_b64encode(hashlib.md5(repr(key)).digest()).rstrip('=').replace('-', '_') asset_file = asset_file + '.png' asset_path = os.path.join(config.ASSETS_ROOT, asset_file) try: new_image.save(asset_path) except IOError: log.exception("Error while saving image") inline = True # Retry inline version url = '%s%s' % (config.ASSETS_URL, asset_file) if inline: output = StringIO() new_image.save(output, format='PNG') contents = output.getvalue() output.close() url = 'data:image/png;base64,' + base64.b64encode(contents) inline = 'url("%s")' % escape(url) return StringValue(inline) def add_cache_buster(url, mtime): fragment = url.split('#') query = fragment[0].split('?') if len(query) > 1 and query[1] != '': cb = '&_=%s' % (mtime) url = '?'.join(query) + cb else: cb = '?_=%s' % (mtime) url = query[0] + cb if len(fragment) > 1: url += '#' + fragment[1] return url def _stylesheet_url(path, only_path=False, cache_buster=True): """ Generates a path to an asset found relative to the project's css directory. Passing a true value as the second argument will cause the only the path to be returned instead of a `url()` function """ filepath = StringValue(path).value if callable(config.STATIC_ROOT): try: _file, _storage = list(config.STATIC_ROOT(filepath))[0] d_obj = _storage.modified_time(_file) filetime = int(time.mktime(d_obj.timetuple())) except: filetime = 'NA' else: _path = os.path.join(config.STATIC_ROOT, filepath.strip('/')) if os.path.exists(_path): filetime = int(os.path.getmtime(_path)) else: filetime = 'NA' BASE_URL = config.STATIC_URL url = '%s%s' % (BASE_URL, filepath) if cache_buster: url = add_cache_buster(url, filetime) if not only_path: url = 'url("%s")' % (url) return StringValue(url) def __font_url(path, only_path=False, cache_buster=True, inline=False): filepath = StringValue(path).value path = None if callable(config.STATIC_ROOT): try: _file, _storage = list(config.STATIC_ROOT(filepath))[0] d_obj = _storage.modified_time(_file) filetime = int(time.mktime(d_obj.timetuple())) if inline: path = _storage.open(_file) except: filetime = 'NA' else: _path = os.path.join(config.STATIC_ROOT, filepath.strip('/')) if os.path.exists(_path): filetime = int(os.path.getmtime(_path)) if inline: path = open(_path, 'rb') else: filetime = 'NA' BASE_URL = config.STATIC_URL if path and inline: mime_type = mimetypes.guess_type(filepath)[0] url = 'data:' + mime_type + ';base64,' + base64.b64encode(path.read()) else: url = '%s%s' % (BASE_URL, filepath) if cache_buster: url = add_cache_buster(url, filetime) if not only_path: url = 'url("%s")' % escape(url) return StringValue(url) def __font_files(args, inline): if len(args) == 1 and isinstance(args[0], (list, tuple, ListValue)): args = ListValue(args[0]).values() n = 0 params = [[], []] for arg in args: if isinstance(arg, ListValue): if len(arg) == 2: if n % 2 == 1: params[1].append(None) n += 1 params[0].append(arg[0]) params[1].append(arg[1]) n += 2 else: for arg2 in arg: params[n % 2].append(arg2) n += 1 else: params[n % 2].append(arg) n += 1 len0 = len(params[0]) len1 = len(params[1]) if len1 < len0: params[1] += [None] * (len0 - len1) elif len0 < len1: params[0] += [None] * (len1 - len0) fonts = [] for font, format in zip(params[0], params[1]): if format: fonts.append('%s format("%s")' % (__font_url(font, inline=inline), StringValue(format).value)) else: fonts.append(__font_url(font, inline=inline)) return ListValue(fonts) def _font_url(path, only_path=False, cache_buster=True): """ Generates a path to an asset found relative to the project's font directory. Passing a true value as the second argument will cause the only the path to be returned instead of a `url()` function """ return __font_url(path, only_path, cache_buster, False) def _font_files(*args): return __font_files(args, inline=False) def _inline_font_files(*args): return __font_files(args, inline=True) def __image_url(path, only_path=False, cache_buster=True, dst_color=None, src_color=None, inline=False, mime_type=None, spacing=None, collapse_x=None, collapse_y=None): """ src_color - a list of or a single color to be replaced by each corresponding dst_color colors spacing - spaces to be added to the image collapse_x, collapse_y - collapsable (layered) image of the given size (x, y) """ if inline or dst_color or spacing: if not Image: raise Exception("Images manipulation require PIL") filepath = StringValue(path).value mime_type = inline and (StringValue(mime_type).value or mimetypes.guess_type(filepath)[0]) path = None if callable(config.STATIC_ROOT): try: _file, _storage = list(config.STATIC_ROOT(filepath))[0] d_obj = _storage.modified_time(_file) filetime = int(time.mktime(d_obj.timetuple())) if inline or dst_color or spacing: path = _storage.open(_file) except: filetime = 'NA' else: _path = os.path.join(config.STATIC_ROOT, filepath.strip('/')) if os.path.exists(_path): filetime = int(os.path.getmtime(_path)) if inline or dst_color or spacing: path = open(_path, 'rb') else: filetime = 'NA' BASE_URL = config.STATIC_URL if path: dst_colors = dst_color if isinstance(dst_colors, ListValue): dst_colors = [list(ColorValue(v).value[:3]) for n, v in dst_colors.items() if v] else: dst_colors = [list(ColorValue(dst_colors).value[:3])] if dst_colors else [] src_colors = src_color if isinstance(src_colors, ListValue): src_colors = [tuple(ColorValue(v).value[:3]) if v else (0, 0, 0) for n, v in src_colors.items()] else: src_colors = [tuple(ColorValue(src_colors).value[:3]) if src_colors else (0, 0, 0)] len_colors = max(len(dst_colors), len(src_colors)) dst_colors = (dst_colors * len_colors)[:len_colors] src_colors = (src_colors * len_colors)[:len_colors] if isinstance(spacing, ListValue): spacing = [int(NumberValue(v).value) for n, v in spacing.items()] else: spacing = [int(NumberValue(spacing).value)] spacing = (spacing * 4)[:4] file_name, file_ext = os.path.splitext(os.path.normpath(filepath).replace('\\', '_').replace('/', '_')) key = (filetime, src_color, dst_color, spacing) key = file_name + '-' + base64.urlsafe_b64encode(hashlib.md5(repr(key)).digest()).rstrip('=').replace('-', '_') asset_file = key + file_ext asset_path = os.path.join(config.ASSETS_ROOT, asset_file) if os.path.exists(asset_path): filepath = asset_file BASE_URL = config.ASSETS_URL if inline: path = open(asset_path, 'rb') url = 'data:' + mime_type + ';base64,' + base64.b64encode(path.read()) else: url = '%s%s' % (BASE_URL, filepath) if cache_buster: filetime = int(os.path.getmtime(asset_path)) url = add_cache_buster(url, filetime) else: image = Image.open(path) width, height = collapse_x or image.size[0], collapse_y or image.size[1] new_image = Image.new( mode='RGBA', size=(width + spacing[1] + spacing[3], height + spacing[0] + spacing[2]), color=(0, 0, 0, 0) ) for i, dst_color in enumerate(dst_colors): src_color = src_colors[i] pixdata = image.load() for _y in xrange(image.size[1]): for _x in xrange(image.size[0]): pixel = pixdata[_x, _y] if pixel[:3] == src_color: pixdata[_x, _y] = tuple([int(c) for c in dst_color] + [pixel[3] if len(pixel) == 4 else 255]) iwidth, iheight = image.size if iwidth != width or iheight != height: cy = 0 while cy < iheight: cx = 0 while cx < iwidth: cropped_image = image.crop((cx, cy, cx + width, cy + height)) new_image.paste(cropped_image, (int(spacing[3]), int(spacing[0])), cropped_image) cx += width cy += height else: new_image.paste(image, (int(spacing[3]), int(spacing[0]))) if not inline: try: new_image.save(asset_path) filepath = asset_file BASE_URL = config.ASSETS_URL if cache_buster: filetime = int(os.path.getmtime(asset_path)) except IOError: log.exception("Error while saving image") inline = True # Retry inline version url = '%s%s' % (config.ASSETS_URL, asset_file) if cache_buster: url = add_cache_buster(url, filetime) if inline: output = StringIO() new_image.save(output, format='PNG') contents = output.getvalue() output.close() url = 'data:' + mime_type + ';base64,' + base64.b64encode(contents) else: url = '%s%s' % (BASE_URL, filepath) if cache_buster: url = add_cache_buster(url, filetime) if not only_path: url = 'url("%s")' % escape(url) return StringValue(url) def _inline_image(image, mime_type=None, dst_color=None, src_color=None, spacing=None, collapse_x=None, collapse_y=None): """ Embeds the contents of a file directly inside your stylesheet, eliminating the need for another HTTP request. For small files such images or fonts, this can be a performance benefit at the cost of a larger generated CSS file. """ return __image_url(image, False, False, dst_color, src_color, True, mime_type, spacing, collapse_x, collapse_y) def _image_url(path, only_path=False, cache_buster=True, dst_color=None, src_color=None, spacing=None, collapse_x=None, collapse_y=None): """ Generates a path to an asset found relative to the project's images directory. Passing a true value as the second argument will cause the only the path to be returned instead of a `url()` function """ return __image_url(path, only_path, cache_buster, dst_color, src_color, False, None, spacing, collapse_x, collapse_y) def _image_width(image): """ Returns the width of the image found at the path supplied by `image` relative to your project's images directory. """ if not Image: raise Exception("Images manipulation require PIL") filepath = StringValue(image).value path = None try: width = sprite_images[filepath][0] except KeyError: width = 0 if callable(config.STATIC_ROOT): try: _file, _storage = list(config.STATIC_ROOT(filepath))[0] path = _storage.open(_file) except: pass else: _path = os.path.join(config.STATIC_ROOT, filepath.strip('/')) if os.path.exists(_path): path = open(_path, 'rb') if path: image = Image.open(path) size = image.size width = size[0] sprite_images[filepath] = size return NumberValue(width, 'px') def _image_height(image): """ Returns the height of the image found at the path supplied by `image` relative to your project's images directory. """ if not Image: raise Exception("Images manipulation require PIL") filepath = StringValue(image).value path = None try: height = sprite_images[filepath][1] except KeyError: height = 0 if callable(config.STATIC_ROOT): try: _file, _storage = list(config.STATIC_ROOT(filepath))[0] path = _storage.open(_file) except: pass else: _path = os.path.join(config.STATIC_ROOT, filepath.strip('/')) if os.path.exists(_path): path = open(_path, 'rb') if path: image = Image.open(path) size = image.size height = size[1] sprite_images[filepath] = size return NumberValue(height, 'px') ################################################################################ def __position(opposite, p): pos = [] hrz = vrt = None nums = [v for v in p if isinstance(v, NumberValue)] if 'left' in p: hrz = 'right' if opposite else 'left' elif 'right' in p: hrz = 'left' if opposite else 'right' elif 'center' in p: hrz = 'center' if 'top' in p: vrt = 'bottom' if opposite else 'top' elif 'bottom' in p: vrt = 'top' if opposite else 'bottom' elif 'center' in p: hrz = 'center' if hrz == vrt: vrt = None if hrz is not None: pos.append(hrz) elif len(nums): pos.append(nums.pop(0)) if vrt is not None: pos.append(vrt) elif len(nums): pos.append(nums.pop(0)) return ListValue(pos + nums) def _position(p): return __position(False, p) def _opposite_position(p): return __position(True, p) def _grad_point(*p): pos = set() hrz = vrt = NumberValue(0.5, '%') for _p in p: pos.update(StringValue(_p).value.split()) if 'left' in pos: hrz = NumberValue(0, '%') elif 'right' in pos: hrz = NumberValue(1, '%') if 'top' in pos: vrt = NumberValue(0, '%') elif 'bottom' in pos: vrt = NumberValue(1, '%') return ListValue(v for v in (hrz, vrt) if v is not None) ################################################################################ def __compass_list(*args): separator = None if len(args) == 1 and isinstance(args[0], (list, tuple, ListValue)): args = ListValue(args[0]).values() else: separator = ',' ret = ListValue(args) if separator: ret['_'] = separator return ret def __compass_space_list(*lst): """ If the argument is a list, it will return a new list that is space delimited Otherwise it returns a new, single element, space-delimited list. """ ret = __compass_list(*lst) ret.value.pop('_', None) return ret def _blank(*objs): """Returns true when the object is false, an empty string, or an empty list""" for o in objs: if bool(o): return BooleanValue(False) return BooleanValue(True) def _compact(*args): """Returns a new list after removing any non-true values""" ret = {} if len(args) == 1: args = args[0] if isinstance(args, ListValue): args = args.value if isinstance(args, dict): for i, item in args.items(): if False if isinstance(item, basestring) and _undefined_re.match(item) else bool(item): ret[i] = item elif False if isinstance(args, basestring) and _undefined_re.match(args) else bool(args): ret[0] = args else: ret['_'] = ',' for i, item in enumerate(args): if False if isinstance(item, basestring) and _undefined_re.match(item) else bool(item): ret[i] = item if isinstance(args, ListValue): args = args.value if isinstance(args, dict): separator = args.get('_', None) if separator is not None: ret['_'] = separator return ListValue(ret) def _reject(lst, *values): """Removes the given values from the list""" ret = {} if not isinstance(lst, ListValue): lst = ListValue(lst) lst = lst.value if len(values) == 1: values = values[0] if isinstance(values, ListValue): values = values.value.values() for i, item in lst.items(): if item not in values: ret[i] = item separator = lst.get('_', None) if separator is not None: ret['_'] = separator return ListValue(ret) def __compass_slice(lst, start_index, end_index=None): start_index = NumberValue(start_index).value end_index = NumberValue(end_index).value if end_index is not None else None ret = {} lst = ListValue(lst).value for i, item in lst.items(): if not isinstance(i, int): if i == '_': ret[i] = item elif i > start_index and end_index is None or i <= end_index: ret[i] = item return ListValue(ret) def _first_value_of(*lst): if len(lst) == 1 and isinstance(lst[0], (list, tuple, ListValue)): lst = ListValue(lst[0]) ret = ListValue(lst).first() return ret.__class__(ret) def _nth(lst, n=1): """ Return the Nth item in the string """ n = StringValue(n).value lst = ListValue(lst).value try: n = int(float(n)) - 1 n = n % len(lst) except: if n.lower() == 'first': n = 0 elif n.lower() == 'last': n = -1 try: ret = lst[n] except KeyError: lst = [v for k, v in sorted(lst.items()) if isinstance(k, int)] try: ret = lst[n] except: ret = '' return ret.__class__(ret) def _join(lst1, lst2, separator=None): ret = ListValue(lst1) lst2 = ListValue(lst2).value lst_len = len(ret.value) ret.value.update((k + lst_len if isinstance(k, int) else k, v) for k, v in lst2.items()) if separator is not None: separator = StringValue(separator).value if separator: ret.value['_'] = separator return ret def _length(*lst): if len(lst) == 1 and isinstance(lst[0], (list, tuple, ListValue)): lst = ListValue(lst[0]).values() lst = ListValue(lst) return NumberValue(len(lst)) def _max(*lst): if len(lst) == 1 and isinstance(lst[0], (list, tuple, ListValue)): lst = ListValue(lst[0]).values() lst = ListValue(lst).value return max(lst.values()) def _min(*lst): if len(lst) == 1 and isinstance(lst[0], (list, tuple, ListValue)): lst = ListValue(lst[0]).values() lst = ListValue(lst).value return min(lst.values()) def _append(lst, val, separator=None): separator = separator and StringValue(separator).value ret = ListValue(lst, separator) val = ListValue(val) for v in val: ret.value[len(ret)] = v return ret ################################################################################ def _prefixed(prefix, *args): to_fnct_str = 'to_' + to_str(prefix).replace('-', '_') for arg in args: if isinstance(arg, ListValue): for k, iarg in arg.value.items(): if hasattr(iarg, to_fnct_str): return BooleanValue(True) else: if hasattr(arg, to_fnct_str): return BooleanValue(True) return BooleanValue(False) def _prefix(prefix, *args): to_fnct_str = 'to_' + to_str(prefix).replace('-', '_') args = list(args) for i, arg in enumerate(args): if isinstance(arg, ListValue): _value = {} for k, iarg in arg.value.items(): to_fnct = getattr(iarg, to_fnct_str, None) if to_fnct: _value[k] = to_fnct() else: _value[k] = iarg args[i] = ListValue(_value) else: to_fnct = getattr(arg, to_fnct_str, None) if to_fnct: args[i] = to_fnct() if len(args) == 1: return args[0] return ListValue(args, ',') def __moz(*args): return _prefix('_moz', *args) def __svg(*args): return _prefix('_svg', *args) def __css2(*args): return _prefix('_css2', *args) def __pie(*args): return _prefix('_pie', *args) def __webkit(*args): return _prefix('_webkit', *args) def __owg(*args): return _prefix('_owg', *args) def __khtml(*args): return _prefix('_khtml', *args) def __ms(*args): return _prefix('_ms', *args) def __o(*args): return _prefix('_o', *args) ################################################################################ def _percentage(value): value = NumberValue(value) value.units = {'%': _units_weights.get('%', 1), '_': '%'} return value def _unitless(value): value = NumberValue(value) return BooleanValue(not bool(value.unit)) def _unquote(*args): return StringValue(' '.join([StringValue(s).value for s in args])) def _quote(*args): return QuotedStringValue(' '.join([StringValue(s).value for s in args])) def _pi(): return NumberValue(math.pi) def _comparable(number1, number2): n1, n2 = NumberValue(number1), NumberValue(number2) type1 = _conv_type.get(n1.unit) type2 = _conv_type.get(n2.unit) return BooleanValue(type1 == type2) def _type_of(obj): # -> bool, number, string, color, list if isinstance(obj, BooleanValue): return StringValue('bool') if isinstance(obj, NumberValue): return StringValue('number') if isinstance(obj, ColorValue): return StringValue('color') if isinstance(obj, ListValue): return StringValue('list') if isinstance(obj, basestring) and _variable_re.match(obj): return StringValue('undefined') return StringValue('string') def _if(condition, if_true, if_false=''): condition = bool(False if not condition or isinstance(condition, basestring) and (condition in ('0', 'false', 'undefined') or _variable_re.match(condition)) else condition) return if_true.__class__(if_true) if condition else if_true.__class__(if_false) def _unit(number): # -> px, em, cm, etc. unit = NumberValue(number).unit return StringValue(unit) __elements_of_type_block = 'address, article, aside, blockquote, center, dd, details, dir, div, dl, dt, fieldset, figcaption, figure, footer, form, frameset, h1, h2, h3, h4, h5, h6, header, hgroup, hr, isindex, menu, nav, noframes, noscript, ol, p, pre, section, summary, ul' __elements_of_type_inline = 'a, abbr, acronym, audio, b, basefont, bdo, big, br, canvas, cite, code, command, datalist, dfn, em, embed, font, i, img, input, kbd, keygen, label, mark, meter, output, progress, q, rp, rt, ruby, s, samp, select, small, span, strike, strong, sub, sup, textarea, time, tt, u, var, video, wbr' __elements_of_type_table = 'table' __elements_of_type_list_item = 'li' __elements_of_type_table_row_group = 'tbody' __elements_of_type_table_header_group = 'thead' __elements_of_type_table_footer_group = 'tfoot' __elements_of_type_table_row = 'tr' __elements_of_type_table_cel = 'td, th' __elements_of_type_html5_block = 'article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary' __elements_of_type_html5_inline = 'audio, canvas, command, datalist, embed, keygen, mark, meter, output, progress, rp, rt, ruby, time, video, wbr' __elements_of_type_html5 = 'article, aside, audio, canvas, command, datalist, details, embed, figcaption, figure, footer, header, hgroup, keygen, mark, menu, meter, nav, output, progress, rp, rt, ruby, section, summary, time, video, wbr' __elements_of_type = { 'block': dict(enumerate(sorted(__elements_of_type_block.replace(' ', '').split(',')))), 'inline': dict(enumerate(sorted(__elements_of_type_inline.replace(' ', '').split(',')))), 'table': dict(enumerate(sorted(__elements_of_type_table.replace(' ', '').split(',')))), 'list-item': dict(enumerate(sorted(__elements_of_type_list_item.replace(' ', '').split(',')))), 'table-row-group': dict(enumerate(sorted(__elements_of_type_table_row_group.replace(' ', '').split(',')))), 'table-header-group': dict(enumerate(sorted(__elements_of_type_table_header_group.replace(' ', '').split(',')))), 'table-footer-group': dict(enumerate(sorted(__elements_of_type_table_footer_group.replace(' ', '').split(',')))), 'table-row': dict(enumerate(sorted(__elements_of_type_table_footer_group.replace(' ', '').split(',')))), 'table-cell': dict(enumerate(sorted(__elements_of_type_table_footer_group.replace(' ', '').split(',')))), 'html5-block': dict(enumerate(sorted(__elements_of_type_html5_block.replace(' ', '').split(',')))), 'html5-inline': dict(enumerate(sorted(__elements_of_type_html5_inline.replace(' ', '').split(',')))), 'html5': dict(enumerate(sorted(__elements_of_type_html5.replace(' ', '').split(',')))), } def _elements_of_type(display): d = StringValue(display) ret = __elements_of_type.get(d.value, None) if ret is None: raise Exception("Elements of type '%s' not found!" % d.value) ret['_'] = ',' return ListValue(ret) def _nest(*arguments): if isinstance(arguments[0], ListValue): lst = arguments[0].values() else: lst = StringValue(arguments[0]).value.split(',') ret = [unicode(s).strip() for s in lst if unicode(s).strip()] for arg in arguments[1:]: if isinstance(arg, ListValue): lst = arg.values() else: lst = StringValue(arg).value.split(',') new_ret = [] for s in lst: s = unicode(s).strip() if s: for r in ret: if '&' in s: new_ret.append(s.replace('&', r)) else: if r[-1] in ('.', ':', '#'): new_ret.append(r + s) else: new_ret.append(r + ' ' + s) ret = new_ret ret = sorted(set(ret)) ret = dict(enumerate(ret)) ret['_'] = ',' return ret def _append_selector(selector, to_append): if isinstance(selector, ListValue): lst = selector.values() else: lst = StringValue(selector).value.split(',') to_append = StringValue(to_append).value.strip() ret = sorted(set(s.strip() + to_append for s in lst if s.strip())) ret = dict(enumerate(ret)) ret['_'] = ',' return ret def _headers(frm=None, to=None): if frm and to is None: if isinstance(frm, StringValue) and frm.value.lower() == 'all': frm = 1 to = 6 else: frm = 1 try: to = int(getattr(frm, 'value', frm)) except ValueError: to = 6 else: try: frm = 1 if frm is None else int(getattr(frm, 'value', frm)) except ValueError: frm = 1 try: to = 6 if to is None else int(getattr(to, 'value', to)) except ValueError: to = 6 ret = ['h' + str(i) for i in range(frm, to + 1)] ret = dict(enumerate(ret)) ret['_'] = ',' return ret def _enumerate(prefix, frm, through, separator='-'): prefix = StringValue(prefix).value separator = StringValue(separator).value try: frm = int(getattr(frm, 'value', frm)) except ValueError: frm = 1 try: through = int(getattr(through, 'value', through)) except ValueError: through = frm if frm > through: frm, through = through, frm rev = reversed else: rev = lambda x: x if prefix: ret = [prefix + separator + str(i) for i in rev(range(frm, through + 1))] else: ret = [NumberValue(i) for i in rev(range(frm, through + 1))] ret = dict(enumerate(ret)) ret['_'] = ',' return ret def _range(frm, through=None): if through is None: through = frm frm = 1 return _enumerate(None, frm, through) ################################################################################ # Specific to pyScss parser functions: def _convert_to(value, type): return value.convert_to(type) def _inv(sign, value): if isinstance(value, NumberValue): return value * -1 elif isinstance(value, BooleanValue): return not value val = StringValue(value) val.value = sign + val.value return val ################################################################################ # pyScss data types: class ParserValue(object): def __init__(self, value): self.value = value class Value(object): @staticmethod def _operatorOperands(tokenlist): "generator to extract operators and operands in pairs" it = iter(tokenlist) while 1: try: yield (it.next(), it.next()) except StopIteration: break @staticmethod def _merge_type(a, b): if a.__class__ == b.__class__: return a.__class__ if isinstance(a, QuotedStringValue) or isinstance(b, QuotedStringValue): return QuotedStringValue return StringValue @staticmethod def _wrap(fn): """ Wrapper function to allow calling any function using Value objects as parameters. """ def _func(*args): merged = None _args = [] for arg in args: if merged.__class__ != arg.__class__: if merged is None: merged = arg.__class__(None) else: merged = Value._merge_type(merged, arg)(None) merged.merge(arg) if isinstance(arg, Value): arg = arg.value _args.append(arg) merged.value = fn(*_args) return merged return _func @classmethod def _do_bitops(cls, first, second, op): first = StringValue(first) second = StringValue(second) k = op(first.value, second.value) return first if first.value == k else second def __repr__(self): return '<%s: %s>' % (self.__class__.__name__, repr(self.value)) def __lt__(self, other): return self._do_cmps(self, other, operator.__lt__) def __le__(self, other): return self._do_cmps(self, other, operator.__le__) def __eq__(self, other): return self._do_cmps(self, other, operator.__eq__) def __ne__(self, other): return self._do_cmps(self, other, operator.__ne__) def __gt__(self, other): return self._do_cmps(self, other, operator.__gt__) def __ge__(self, other): return self._do_cmps(self, other, operator.__ge__) def __cmp__(self, other): return self._do_cmps(self, other, operator.__cmp__) def __rcmp__(self, other): return self._do_cmps(other, self, operator.__cmp__) def __and__(self, other): return self._do_bitops(self, other, operator.__and__) def __or__(self, other): return self._do_bitops(self, other, operator.__or__) def __xor__(self, other): return self._do_bitops(self, other, operator.__xor__) def __rand__(self, other): return self._do_bitops(other, self, operator.__rand__) def __ror__(self, other): return self._do_bitops(other, self, operator.__ror__) def __rxor__(self, other): return self._do_bitops(other, self, operator.__rxor__) def __nonzero__(self): return bool(self.value) def __add__(self, other): return self._do_op(self, other, operator.__add__) def __radd__(self, other): return self._do_op(other, self, operator.__add__) def __div__(self, other): return self._do_op(self, other, operator.__div__) def __rdiv__(self, other): return self._do_op(other, self, operator.__div__) def __sub__(self, other): return self._do_op(self, other, operator.__sub__) def __rsub__(self, other): return self._do_op(other, self, operator.__sub__) def __mul__(self, other): return self._do_op(self, other, operator.__mul__) def __rmul__(self, other): return self._do_op(other, self, operator.__mul__) def convert_to(self, type): return self.value.convert_to(type) def merge(self, obj): if isinstance(obj, Value): self.value = obj.value else: self.value = obj return self class BooleanValue(Value): def __init__(self, tokens): self.tokens = tokens if tokens is None: self.value = False elif isinstance(tokens, ParserValue): self.value = (tokens.value.lower() == 'true') elif isinstance(tokens, BooleanValue): self.value = tokens.value elif isinstance(tokens, NumberValue): self.value = bool(tokens.value) elif isinstance(tokens, (float, int)): self.value = bool(tokens) else: self.value = to_str(tokens).lower() in ('true', '1', 'on', 'yes', 't', 'y') or bool(tokens) def __hash__(self): return hash(self.value) def __str__(self): return 'true' if self.value else 'false' @classmethod def _do_cmps(cls, first, second, op): first = first.value if isinstance(first, Value) else first second = second.value if isinstance(second, Value) else second if first in ('true', '1', 'on', 'yes', 't', 'y'): first = True elif first in ('false', '0', 'off', 'no', 'f', 'n', 'undefined'): first = False if second in ('true', '1', 'on', 'yes', 't', 'y'): second = True elif second in ('false', '0', 'off', 'no', 'f', 'n', 'undefined'): second = False return op(first, second) @classmethod def _do_op(cls, first, second, op): if isinstance(first, ListValue) and isinstance(second, ListValue): ret = ListValue(first) for k, v in ret.items(): try: ret.value[k] = op(ret.value[k], second.value[k]) except KeyError: pass return ret if isinstance(first, ListValue): ret = ListValue(first) for k, v in ret.items(): ret.value[k] = op(ret.value[k], second) return ret if isinstance(second, ListValue): ret = ListValue(second) for k, v in ret.items(): ret.value[k] = op(first, ret.value[k]) return ret first = BooleanValue(first) second = BooleanValue(second) val = op(first.value, second.value) ret = BooleanValue(None).merge(first).merge(second) ret.value = val return ret def merge(self, obj): obj = BooleanValue(obj) self.value = obj.value return self class NumberValue(Value): def __init__(self, tokens, type=None): self.tokens = tokens self.units = {} if tokens is None: self.value = 0.0 elif isinstance(tokens, ParserValue): self.value = float(tokens.value) elif isinstance(tokens, NumberValue): self.value = tokens.value self.units = tokens.units.copy() if tokens.units: type = None elif isinstance(tokens, (StringValue, basestring)): tokens = getattr(tokens, 'value', tokens) if _undefined_re.match(tokens): raise ValueError("Value is not a Number! (%s)" % tokens) try: if tokens and tokens[-1] == '%': self.value = to_float(tokens[:-1]) / 100.0 self.units = {'%': _units_weights.get('%', 1), '_': '%'} else: self.value = to_float(tokens) except ValueError: raise ValueError("Value is not a Number! (%s)" % tokens) elif isinstance(tokens, (int, float)): self.value = float(tokens) elif isinstance(tokens, (list, tuple)): raise ValueError("Value is not a Number! (%r)" % list(tokens)) elif isinstance(tokens, (dict, ListValue)): raise ValueError("Value is not a Number! (%r)" % tokens.values()) else: raise ValueError("Value is not a Number! (%s)" % tokens) if type is not None: self.units = {type: _units_weights.get(type, 1), '_': type} def __hash__(self): return hash((self.value, frozenset(self.units.items()))) def __repr__(self): return '<%s: %s, %s>' % (self.__class__.__name__, repr(self.value), repr(self.units)) def __int__(self): return int(self.value) def __float__(self): return float(self.value) def __str__(self): unit = self.unit val = self.value / _conv_factor.get(unit, 1.0) val = to_str(val) + unit return val @classmethod def _do_cmps(cls, first, second, op): try: first = NumberValue(first) second = NumberValue(second) except ValueError: return op(getattr(first, 'value', first), getattr(second, 'value', second)) first_type = _conv_type.get(first.unit) second_type = _conv_type.get(second.unit) if first_type == second_type or first_type is None or second_type is None: return op(first.value, second.value) else: return op(first_type, second_type) @classmethod def _do_op(cls, first, second, op): if isinstance(first, ListValue) and isinstance(second, ListValue): ret = ListValue(first) for k, v in ret.items(): try: ret.value[k] = op(ret.value[k], second.value[k]) except KeyError: pass return ret if isinstance(first, ListValue): ret = ListValue(first) for k, v in ret.items(): ret.value[k] = op(ret.value[k], second) return ret if isinstance(second, ListValue): ret = ListValue(second) for k, v in ret.items(): ret.value[k] = op(first, ret.value[k]) return ret if isinstance(first, basestring): first = StringValue(first) elif isinstance(first, (int, float)): first = NumberValue(first) if isinstance(second, basestring): second = StringValue(second) elif isinstance(second, (int, float)): second = NumberValue(second) if op in (operator.__div__, operator.__sub__): if isinstance(first, QuotedStringValue): first = NumberValue(first) if isinstance(second, QuotedStringValue): second = NumberValue(second) elif op == operator.__mul__: if isinstance(first, NumberValue) and isinstance(second, QuotedStringValue): first.value = int(first.value) val = op(second.value, first.value) return second.__class__(val) if isinstance(first, QuotedStringValue) and isinstance(second, NumberValue): second.value = int(second.value) val = op(first.value, second.value) return first.__class__(val) if not isinstance(first, NumberValue) or not isinstance(second, NumberValue): return op(first.value if isinstance(first, NumberValue) else first, second.value if isinstance(second, NumberValue) else second) first_unit = first.unit second_unit = second.unit if op == operator.__add__ or op == operator.__sub__: if first_unit == '%' and not second_unit: second.units = {'%': _units_weights.get('%', 1), '_': '%'} second.value /= 100.0 elif first_unit == '%' and second_unit != '%': first = NumberValue(second) * first.value elif second_unit == '%' and not first_unit: first.units = {'%': _units_weights.get('%', 1), '_': '%'} first.value /= 100.0 elif second_unit == '%' and first_unit != '%': second = NumberValue(first) * second.value val = op(first.value, second.value) ret = NumberValue(None).merge(first) ret = ret.merge(second) ret.value = val return ret def merge(self, obj): obj = NumberValue(obj) self.value = obj.value for unit, val in obj.units.items(): if unit != '_': self.units.setdefault(unit, 0) self.units[unit] += val unit = obj.unit if _units_weights.get(self.units.get('_'), 1) <= _units_weights.get(unit, 1): self.units['_'] = unit return self def convert_to(self, type): val = self.value if not self.unit: val *= _conv_factor.get(type, 1.0) ret = NumberValue(val) if type == 'deg': ret.value = ret.value % 360.0 ret.units = {type: _units_weights.get(type, 1), '_': type} return ret @property def unit(self): unit = '' if self.units: if '_'in self.units: units = self.units.copy() _unit = units.pop('_') units.setdefault(_unit, 0) units[_unit] += _units_weights.get(_unit, 1) # Give more weight to the first unit ever set else: units = self.units units = sorted(units, key=units.get) while len(units): unit = units.pop() if unit: break return unit class ListValue(Value): def __init__(self, tokens, separator=None): self.tokens = tokens if tokens is None: self.value = {} elif isinstance(tokens, ParserValue): self.value = self._reorder_list(tokens.value) elif isinstance(tokens, ListValue): self.value = tokens.value.copy() elif isinstance(tokens, Value): self.value = {0: tokens} elif isinstance(tokens, dict): self.value = self._reorder_list(tokens) elif isinstance(tokens, (list, tuple)): self.value = dict(enumerate(tokens)) else: if isinstance(tokens, StringValue): tokens = tokens.value tokens = to_str(tokens) lst = [i for i in tokens.split() if i] if len(lst) == 1: lst = [i.strip() for i in lst[0].split(',') if i.strip()] if len(lst) > 1: separator = ',' if separator is None else separator else: lst = [tokens] self.value = dict(enumerate(lst)) if separator is None: separator = self.value.pop('_', None) if separator: self.value['_'] = separator def __hash__(self): return hash((frozenset(self.value.items()))) @classmethod def _do_cmps(cls, first, second, op): try: first = ListValue(first) second = ListValue(second) except ValueError: return op(getattr(first, 'value', first), getattr(second, 'value', second)) return op(first.value, second.value) @classmethod def _do_op(cls, first, second, op): if isinstance(first, ListValue) and isinstance(second, ListValue): ret = ListValue(first) for k, v in ret.items(): try: ret.value[k] = op(ret.value[k], second.value[k]) except KeyError: pass return ret if isinstance(first, ListValue): ret = ListValue(first) for k, v in ret.items(): ret.value[k] = op(ret.value[k], second) return ret if isinstance(second, ListValue): ret = ListValue(second) for k, v in ret.items(): ret.value[k] = op(first, ret.value[k]) return ret def _reorder_list(self, lst): return dict((i if isinstance(k, int) else k, v) for i, (k, v) in enumerate(sorted(lst.items()))) def __nonzero__(self): return len(self) def __len__(self): return len(self.value) - (1 if '_' in self.value else 0) def __str__(self): return to_str(self.value) def __tuple__(self): return tuple(sorted((k, v) for k, v in self.value.items() if k != '_')) def __iter__(self): return iter(self.values()) def values(self): return zip(*self.items())[1] def keys(self): return zip(*self.items())[1] def items(self): return sorted((k, v) for k, v in self.value.items() if k != '_') def first(self): for v in self.values(): if isinstance(v, basestring) and _undefined_re.match(v): continue if bool(v): return v return v class ColorValue(Value): def __init__(self, tokens): self.tokens = tokens self.value = (0, 0, 0, 1) self.types = {} if tokens is None: self.value = (0, 0, 0, 1) elif isinstance(tokens, ParserValue): hex = tokens.value self.value = hex2rgba[len(hex)](hex) self.types = {'rgba': 1} elif isinstance(tokens, ColorValue): self.value = tokens.value self.types = tokens.types.copy() elif isinstance(tokens, NumberValue): val = tokens.value self.value = (val, val, val, 1) elif isinstance(tokens, (list, tuple)): c = tokens[:4] r = 255.0, 255.0, 255.0, 1.0 c = [0.0 if c[i] < 0 else r[i] if c[i] > r[i] else c[i] for i in range(4)] self.value = tuple(c) type = tokens[-1] if type in ('rgb', 'rgba', 'hsl', 'hsla'): self.types = {type: 1} elif isinstance(tokens, (int, float)): val = float(tokens) self.value = (val, val, val, 1) else: if isinstance(tokens, StringValue): tokens = tokens.value tokens = to_str(tokens) tokens.replace(' ', '').lower() if _undefined_re.match(tokens): raise ValueError("Value is not a Color! (%s)" % tokens) try: self.value = hex2rgba[len(tokens)](tokens) except: try: val = to_float(tokens) self.value = (val, val, val, 1) except ValueError: try: type, _, colors = tokens.partition('(') colors = colors.rstrip(')') if type in ('rgb', 'rgba'): c = tuple(colors.split(',')) try: c = [to_float(c[i]) for i in range(4)] col = [0.0 if c[i] < 0 else 255.0 if c[i] > 255 else c[i] for i in range(3)] col += [0.0 if c[3] < 0 else 1.0 if c[3] > 1 else c[3]] self.value = tuple(col) self.types = {type: 1} except: raise ValueError("Value is not a Color! (%s)" % tokens) elif type in ('hsl', 'hsla'): c = colors.split(',') try: c = [to_float(c[i]) for i in range(4)] col = [c[0] % 360.0] / 360.0 col += [0.0 if c[i] < 0 else 1.0 if c[i] > 1 else c[i] for i in range(1, 4)] self.value = tuple([c * 255.0 for c in colorsys.hls_to_rgb(col[0], 0.999999 if col[2] == 1 else col[2], 0.999999 if col[1] == 1 else col[1])] + [col[3]]) self.types = {type: 1} except: raise ValueError("Value is not a Color! (%s)" % tokens) else: raise ValueError("Value is not a Color! (%s)" % tokens) except: raise ValueError("Value is not a Color! (%s)" % tokens) def __hash__(self): return hash((tuple(self.value), frozenset(self.types.items()))) def __repr__(self): return '<%s: %s, %s>' % (self.__class__.__name__, repr(self.value), repr(self.types)) def __str__(self): type = self.type c = self.value if type == 'hsl' or type == 'hsla' and c[3] == 1: h, l, s = colorsys.rgb_to_hls(c[0] / 255.0, c[1] / 255.0, c[2] / 255.0) return 'hsl(%s, %s%%, %s%%)' % (to_str(h * 360.0), to_str(s * 100.0), to_str(l * 100.0)) if type == 'hsla': h, l, s = colorsys.rgb_to_hls(c[0] / 255.0, c[1] / 255.0, c[2] / 255.0) return 'hsla(%s, %s%%, %s%%, %s)' % (to_str(h * 360.0), to_str(s * 100.0), to_str(l * 100.0), to_str(c[3])) r, g, b = to_str(c[0]), to_str(c[1]), to_str(c[2]) _, _, r = r.partition('.') _, _, g = g.partition('.') _, _, b = b.partition('.') if c[3] == 1: if len(r) > 2 or len(g) > 2 or len(b) > 2: return 'rgb(%s%%, %s%%, %s%%)' % (to_str(c[0] * 100.0 / 255.0), to_str(c[1] * 100.0 / 255.0), to_str(c[2] * 100.0 / 255.0)) return '#%02x%02x%02x' % (round(c[0]), round(c[1]), round(c[2])) if len(r) > 2 or len(g) > 2 or len(b) > 2: return 'rgba(%s%%, %s%%, %s%%, %s)' % (to_str(c[0] * 100.0 / 255.0), to_str(c[1] * 100.0 / 255.0), to_str(c[2] * 100.0 / 255.0), to_str(c[3])) return 'rgba(%d, %d, %d, %s)' % (round(c[0]), round(c[1]), round(c[2]), to_str(c[3])) @classmethod def _do_cmps(cls, first, second, op): try: first = ColorValue(first) second = ColorValue(second) except ValueError: return op(getattr(first, 'value', first), getattr(second, 'value', second)) return op(first.value, second.value) @classmethod def _do_op(cls, first, second, op): if isinstance(first, ListValue) and isinstance(second, ListValue): ret = ListValue(first) for k, v in ret.items(): try: ret.value[k] = op(ret.value[k], second.value[k]) except KeyError: pass return ret if isinstance(first, ListValue): ret = ListValue(first) for k, v in ret.items(): ret.value[k] = op(ret.value[k], second) return ret if isinstance(second, ListValue): ret = ListValue(second) for k, v in ret.items(): ret.value[k] = op(first, ret.value[k]) return ret first = ColorValue(first) second = ColorValue(second) val = [op(first.value[i], second.value[i]) for i in range(4)] val[3] = (first.value[3] + second.value[3]) / 2 c = val r = 255.0, 255.0, 255.0, 1.0 c = [0.0 if c[i] < 0 else r[i] if c[i] > r[i] else c[i] for i in range(4)] ret = ColorValue(None).merge(first).merge(second) ret.value = tuple(c) return ret def merge(self, obj): obj = ColorValue(obj) self.value = obj.value for type, val in obj.types.items(): self.types.setdefault(type, 0) self.types[type] += val return self def convert_to(self, type): val = self.value ret = ColorValue(val) ret.types[type] = 1 return ret @property def type(self): type = '' if self.types: types = sorted(self.types, key=self.types.get) while len(types): type = types.pop() if type: break return type class QuotedStringValue(Value): def __init__(self, tokens): self.tokens = tokens if tokens is None: self.value = '' elif isinstance(tokens, ParserValue): self.value = dequote(tokens.value) elif isinstance(tokens, QuotedStringValue): self.value = tokens.value else: self.value = to_str(tokens) def __hash__(self): return hash((True, self.value)) def convert_to(self, type): return QuotedStringValue(self.value + type) def __str__(self): return str(self.__unicode__()) def __unicode__(self): return '"%s"' % escape(self.value) @classmethod def _do_cmps(cls, first, second, op): first = QuotedStringValue(first) second = QuotedStringValue(second) return op(first.value, second.value) @classmethod def _do_op(cls, first, second, op): if isinstance(first, ListValue) and isinstance(second, ListValue): ret = ListValue(first) for k, v in ret.items(): try: ret.value[k] = op(ret.value[k], second.value[k]) except KeyError: pass return ret if isinstance(first, ListValue): ret = ListValue(first) for k, v in ret.items(): ret.value[k] = op(ret.value[k], second) return ret if isinstance(second, ListValue): ret = ListValue(second) for k, v in ret.items(): ret.value[k] = op(first, ret.value[k]) return ret first = QuotedStringValue(first) first_value = first.value if op == operator.__mul__: second = NumberValue(second) second_value = int(second.value) else: second = QuotedStringValue(second) second_value = second.value val = op(first_value, second_value) ret = QuotedStringValue(None).merge(first).merge(second) ret.value = val return ret def merge(self, obj): obj = QuotedStringValue(obj) self.value = obj.value return self class StringValue(QuotedStringValue): def __hash__(self): return hash((False, self.value)) def __str__(self): return str(self.__unicode__()) def __unicode__(self): return self.value def __add__(self, other): if isinstance(other, ListValue): return self._do_op(self, other, operator.__add__) string_class = StringValue if self.__class__ == QuotedStringValue or other.__class__ == QuotedStringValue: string_class = QuotedStringValue other = string_class(other) if not isinstance(other, (QuotedStringValue, basestring)): return string_class(self.value + '+' + other.value) return string_class(self.value + other.value) def __radd__(self, other): if isinstance(other, ListValue): return self._do_op(other, self, operator.__add__) string_class = StringValue if self.__class__ == QuotedStringValue or other.__class__ == QuotedStringValue: string_class = QuotedStringValue other = string_class(other) if not isinstance(other, (QuotedStringValue, basestring)): return string_class(other.value + '+' + self.value) return string_class(other.value + self.value) # Parser/functions map: fnct = { 'grid-image:4': _grid_image, 'grid-image:5': _grid_image, 'image-color:1': _image_color, 'image-color:2': _image_color, 'image-color:3': _image_color, 'sprite-map:1': _sprite_map, 'sprite-names:1': _sprites, 'sprites:1': _sprites, 'sprite:2': _sprite, 'sprite:3': _sprite, 'sprite:4': _sprite, 'sprite-map-name:1': _sprite_map_name, 'sprite-file:2': _sprite_file, 'sprite-url:1': _sprite_url, 'sprite-position:2': _sprite_position, 'sprite-position:3': _sprite_position, 'sprite-position:4': _sprite_position, 'background-noise:0': _background_noise, 'background-noise:1': _background_noise, 'background-noise:2': _background_noise, 'background-noise:3': _background_noise, 'background-noise:4': _background_noise, 'image-url:1': _image_url, 'image-url:2': _image_url, 'image-url:3': _image_url, 'image-url:4': _image_url, 'image-url:5': _image_url, 'inline-image:1': _inline_image, 'inline-image:2': _inline_image, 'image-width:1': _image_width, 'image-height:1': _image_height, 'stylesheet-url:1': _stylesheet_url, 'stylesheet-url:2': _stylesheet_url, 'font-url:1': _font_url, 'font-url:2': _font_url, 'font-files:n': _font_files, 'inline-font-files:n': _inline_font_files, 'opposite-position:n': _opposite_position, 'grad-point:n': _grad_point, 'grad-end-position:n': _grad_end_position, 'color-stops:n': _color_stops, 'color-stops-in-percentages:n': _color_stops_in_percentages, 'grad-color-stops:n': _grad_color_stops, 'radial-gradient:n': _radial_gradient, 'linear-gradient:n': _linear_gradient, 'radial-svg-gradient:n': _radial_svg_gradient, 'linear-svg-gradient:n': _linear_svg_gradient, 'opacify:2': _opacify, 'fadein:2': _opacify, 'fade-in:2': _opacify, 'transparentize:2': _transparentize, 'fadeout:2': _transparentize, 'fade-out:2': _transparentize, 'lighten:2': _lighten, 'darken:2': _darken, 'saturate:2': _saturate, 'desaturate:2': _desaturate, 'grayscale:1': _grayscale, 'greyscale:1': _grayscale, 'adjust-hue:2': _adjust_hue, 'adjust-lightness:2': _adjust_lightness, 'adjust-saturation:2': _adjust_saturation, 'scale-lightness:2': _scale_lightness, 'scale-saturation:2': _scale_saturation, 'adjust-color:n': _adjust_color, 'scale-color:n': _scale_color, 'change-color:n': _change_color, 'spin:2': _adjust_hue, 'complement:1': _complement, 'invert:1': _invert, 'mix:2': _mix, 'mix:3': _mix, 'hsl:3': _hsl, 'hsl:1': _hsl2, 'hsla:1': _hsla2, 'hsla:2': _hsla2, 'hsla:4': _hsla, 'rgb:3': _rgb, 'rgb:1': _rgb2, 'rgba:1': _rgba2, 'rgba:2': _rgba2, 'rgba:4': _rgba, 'ie-hex-str:1': _ie_hex_str, 'red:1': _red, 'green:1': _green, 'blue:1': _blue, 'alpha:1': _alpha, 'opacity:1': _alpha, 'hue:1': _hue, 'saturation:1': _saturation, 'lightness:1': _lightness, 'prefixed:n': _prefixed, 'prefix:n': _prefix, '-moz:n': __moz, '-svg:n': __svg, '-css2:n': __css2, '-pie:n': __pie, '-webkit:n': __webkit, '-owg:n': __owg, '-ms:n': __ms, '-o:n': __o, '-compass-list:n': __compass_list, '-compass-space-list:n': __compass_space_list, 'blank:n': _blank, 'compact:n': _compact, 'reject:n': _reject, '-compass-slice:3': __compass_slice, 'nth:2': _nth, 'max:n': _max, 'min:n': _min, '-compass-nth:2': _nth, 'first-value-of:n': _first_value_of, 'join:2': _join, 'join:3': _join, 'length:n': _length, '-compass-list-size:n': _length, 'append:2': _append, 'append:3': _append, 'nest:n': _nest, 'append-selector:2': _append_selector, 'headers:0': _headers, 'headers:1': _headers, 'headers:2': _headers, 'headings:0': _headers, 'headings:1': _headers, 'headings:2': _headers, 'enumerate:3': _enumerate, 'enumerate:4': _enumerate, 'range:1': _range, 'range:2': _range, 'percentage:1': _percentage, 'unitless:1': _unitless, 'unit:1': _unit, 'if:2': _if, 'if:3': _if, 'type-of:1': _type_of, 'comparable:2': _comparable, 'elements-of-type:1': _elements_of_type, 'quote:n': _quote, 'unquote:n': _unquote, 'escape:1': _unquote, 'e:1': _unquote, 'sin:1': Value._wrap(math.sin), 'cos:1': Value._wrap(math.cos), 'tan:1': Value._wrap(math.tan), 'abs:1': Value._wrap(abs), 'round:1': Value._wrap(round), 'ceil:1': Value._wrap(math.ceil), 'floor:1': Value._wrap(math.floor), 'pi:0': _pi, } for u in _units: fnct[u + ':2'] = _convert_to def interpolate(v, R): C, O = R[CONTEXT], R[OPTIONS] vi = C.get(v, v) if v != vi and isinstance(vi, basestring): _vi = eval_expr(vi, R, True) if _vi is not None: vi = _vi return vi def call(name, args, R, is_function=True): C, O = R[CONTEXT], R[OPTIONS] # Function call: _name = name.replace('_', '-') s = args and args.value.items() or [] _args = [v for n, v in s if isinstance(n, int)] _kwargs = dict((str(n[1:]).replace('-', '_'), v) for n, v in s if not isinstance(n, int) and n != '_') _fn_a = '%s:%d' % (_name, len(_args)) #print >>sys.stderr, '#', _fn_a, _args, _kwargs _fn_n = '%s:n' % _name try: fn = O and O.get('@function ' + _fn_a) if fn: node = fn(R, *_args, **_kwargs) else: fn = fnct.get(_fn_a) or fnct[_fn_n] node = fn(*_args, **_kwargs) except KeyError: sp = args and args.value.get('_') or '' if is_function: if not _css_functions_re.match(_name): log.error("Required function not found: %s (%s)", _fn_a, R[INDEX][R[LINENO]], extra={'stack': True}) _args = (sp + ' ').join(to_str(v) for n, v in s if isinstance(n, int)) _kwargs = (sp + ' ').join('%s: %s' % (n, to_str(v)) for n, v in s if not isinstance(n, int) and n != '_') if _args and _kwargs: _args += (sp + ' ') # Function not found, simply write it as a string: node = StringValue(name + '(' + _args + _kwargs + ')') else: node = StringValue((sp + ' ').join(str(v) for n, v in s if n != '_')) return node ################################################################################ # Parser if not Scanner: class NoMoreTokens(Exception): """ Another exception object, for when we run out of tokens """ pass class Scanner(object): def __init__(self, patterns, ignore, input=None): """ Patterns is [(terminal,regex)...] Ignore is [terminal,...]; Input is a string """ self.reset(input) self.ignore = ignore # The stored patterns are a pair (compiled regex,source # regex). If the patterns variable passed in to the # constructor is None, we assume that the class already has a # proper .patterns list constructed if patterns is not None: self.patterns = [] for k, r in patterns: self.patterns.append((k, re.compile(r))) def reset(self, input): self.tokens = [] self.restrictions = [] self.input = input self.pos = 0 def __repr__(self): """ Print the last 10 tokens that have been scanned in """ output = '' for t in self.tokens[-10:]: output = "%s\n (@%s) %s = %s" % (output, t[0], t[2], repr(t[3])) return output def _scan(self, restrict): """ Should scan another token and add it to the list, self.tokens, and add the restriction to self.restrictions """ # Keep looking for a token, ignoring any in self.ignore token = None while True: best_pat = None # Search the patterns for a match, with earlier # tokens in the list having preference best_pat_len = 0 for p, regexp in self.patterns: # First check to see if we're restricting to this token if restrict and p not in restrict and p not in self.ignore: continue m = regexp.match(self.input, self.pos) if m: # We got a match best_pat = p best_pat_len = len(m.group(0)) break # If we didn't find anything, raise an error if best_pat is None: msg = "Bad Token" if restrict: msg = "Trying to find one of " + ", ".join(restrict) raise SyntaxError("SyntaxError[@ char %s: %s]" % (repr(self.pos), msg)) # If we found something that isn't to be ignored, return it if best_pat in self.ignore: # This token should be ignored... self.pos += best_pat_len else: end_pos = self.pos + best_pat_len # Create a token with this data token = ( self.pos, end_pos, best_pat, self.input[self.pos:end_pos] ) break if token is not None: self.pos = token[1] # Only add this token if it's not in the list # (to prevent looping) if not self.tokens or token != self.tokens[-1]: self.tokens.append(token) self.restrictions.append(restrict) return 1 return 0 def token(self, i, restrict=None): """ Get the i'th token, and if i is one past the end, then scan for another token; restrict is a list of tokens that are allowed, or 0 for any token. """ tokens_len = len(self.tokens) if i == tokens_len: # We are at the end, get the next... tokens_len += self._scan(restrict) if i < tokens_len: if restrict and self.restrictions[i] and restrict > self.restrictions[i]: raise NotImplementedError("Unimplemented: restriction set changed") return self.tokens[i] raise NoMoreTokens def rewind(self, i): tokens_len = len(self.tokens) if i <= tokens_len: token = self.tokens[i] self.tokens = self.tokens[:i] self.restrictions = self.restrictions[:i] self.pos = token[0] class CachedScanner(Scanner): """ Same as Scanner, but keeps cached tokens for any given input """ _cache_ = {} _goals_ = ['END'] @classmethod def cleanup(cls): cls._cache_ = {} def __init__(self, patterns, ignore, input=None): try: self._tokens = self._cache_[input] except KeyError: self._tokens = None self.__tokens = {} self.__input = input super(CachedScanner, self).__init__(patterns, ignore, input) def reset(self, input): try: self._tokens = self._cache_[input] except KeyError: self._tokens = None self.__tokens = {} self.__input = input super(CachedScanner, self).reset(input) def __repr__(self): if self._tokens is None: return super(CachedScanner, self).__repr__() output = '' for t in self._tokens[-10:]: output = "%s\n (@%s) %s = %s" % (output, t[0], t[2], repr(t[3])) return output def token(self, i, restrict=None): if self._tokens is None: token = super(CachedScanner, self).token(i, restrict) self.__tokens[i] = token if token[2] in self._goals_: # goal tokens self._cache_[self.__input] = self._tokens = self.__tokens return token else: token = self._tokens.get(i) if token is None: raise NoMoreTokens return token def rewind(self, i): if self._tokens is None: super(CachedScanner, self).rewind(i) class Parser(object): def __init__(self, scanner): self._scanner = scanner self._pos = 0 def reset(self, input): self._scanner.reset(input) self._pos = 0 def _peek(self, types): """ Returns the token type for lookahead; if there are any args then the list of args is the set of token types to allow """ tok = self._scanner.token(self._pos, types) return tok[2] def _scan(self, type): """ Returns the matched text, and moves to the next token """ tok = self._scanner.token(self._pos, set([type])) if tok[2] != type: raise SyntaxError("SyntaxError[@ char %s: %s]" % (repr(tok[0]), "Trying to find " + type)) self._pos += 1 return tok[3] def _rewind(self, n=1): self._pos -= min(n, self._pos) self._scanner.rewind(self._pos) ################################################################################ #'(?='), ('LT', '<'), ('GT', '>'), ('STR', "'[^']*'"), ('QSTR', '"[^"]*"'), ('UNITS', '(? a_expr) elif _token_ == 'LE': LE = self._scan('LE') a_expr = self.a_expr(R) v = 'undefined' if isinstance(v, basestring) and _undefined_re.match(v) or isinstance(a_expr, basestring) and _undefined_re.match(a_expr) else (v <= a_expr) elif _token_ == 'GE': GE = self._scan('GE') a_expr = self.a_expr(R) v = 'undefined' if isinstance(v, basestring) and _undefined_re.match(v) or isinstance(a_expr, basestring) and _undefined_re.match(a_expr) else (v >= a_expr) elif _token_ == 'EQ': EQ = self._scan('EQ') a_expr = self.a_expr(R) v = (None if isinstance(v, basestring) and _undefined_re.match(v) else v) == (None if isinstance(a_expr, basestring) and _undefined_re.match(a_expr) else a_expr) else: # == 'NE' NE = self._scan('NE') a_expr = self.a_expr(R) v = (None if isinstance(v, basestring) and _undefined_re.match(v) else v) != (None if isinstance(a_expr, basestring) and _undefined_re.match(a_expr) else a_expr) return v def a_expr(self, R): m_expr = self.m_expr(R) v = m_expr while self._peek(self.a_expr_rsts) in self.a_expr_chks: _token_ = self._peek(self.a_expr_chks) if _token_ == 'ADD': ADD = self._scan('ADD') m_expr = self.m_expr(R) v = 'undefined' if isinstance(v, basestring) and _undefined_re.match(v) or isinstance(m_expr, basestring) and _undefined_re.match(m_expr) else (v + m_expr) else: # == 'SUB' SUB = self._scan('SUB') m_expr = self.m_expr(R) v = 'undefined' if isinstance(v, basestring) and _undefined_re.match(v) or isinstance(m_expr, basestring) and _undefined_re.match(m_expr) else (v - m_expr) return v def m_expr(self, R): u_expr = self.u_expr(R) v = u_expr while self._peek(self.m_expr_rsts) in self.m_expr_chks: _token_ = self._peek(self.m_expr_chks) if _token_ == 'MUL': MUL = self._scan('MUL') u_expr = self.u_expr(R) v = 'undefined' if isinstance(v, basestring) and _undefined_re.match(v) or isinstance(u_expr, basestring) and _undefined_re.match(u_expr) else (v * u_expr) else: # == 'DIV' DIV = self._scan('DIV') u_expr = self.u_expr(R) v = 'undefined' if isinstance(v, basestring) and _undefined_re.match(v) or isinstance(u_expr, basestring) and _undefined_re.match(u_expr) else (v / u_expr) return v def u_expr(self, R): _token_ = self._peek(self.u_expr_rsts) if _token_ == 'SIGN': SIGN = self._scan('SIGN') u_expr = self.u_expr(R) return 'undefined' if isinstance(u_expr, basestring) and _undefined_re.match(u_expr) else _inv('-', u_expr) elif _token_ == 'ADD': ADD = self._scan('ADD') u_expr = self.u_expr(R) return 'undefined' if isinstance(u_expr, basestring) and _undefined_re.match(u_expr) else u_expr else: # in self.u_expr_chks atom = self.atom(R) v = atom if self._peek(self.u_expr_rsts_) == 'UNITS': UNITS = self._scan('UNITS') v = call(UNITS, ListValue(ParserValue({0: v, 1: UNITS})), R, False) return v def atom(self, R): _token_ = self._peek(self.u_expr_chks) if _token_ == 'LPAR': LPAR = self._scan('LPAR') expr_lst = self.expr_lst(R) RPAR = self._scan('RPAR') return expr_lst.first() if len(expr_lst) == 1 else expr_lst elif _token_ == 'ID': ID = self._scan('ID') return ID elif _token_ == 'FNCT': FNCT = self._scan('FNCT') v = None LPAR = self._scan('LPAR') if self._peek(self.atom_rsts) != 'RPAR': expr_lst = self.expr_lst(R) v = expr_lst RPAR = self._scan('RPAR') return call(FNCT, v, R) elif _token_ == 'NUM': NUM = self._scan('NUM') return NumberValue(ParserValue(NUM)) elif _token_ == 'STR': STR = self._scan('STR') return StringValue(ParserValue(STR)) elif _token_ == 'QSTR': QSTR = self._scan('QSTR') return QuotedStringValue(ParserValue(QSTR)) elif _token_ == 'BOOL': BOOL = self._scan('BOOL') return BooleanValue(ParserValue(BOOL)) elif _token_ == 'COLOR': COLOR = self._scan('COLOR') return ColorValue(ParserValue(COLOR)) else: # == 'VAR' VAR = self._scan('VAR') return interpolate(VAR, R) def expr_lst(self, R): n = None if self._peek(self.expr_lst_rsts) == 'VAR': VAR = self._scan('VAR') if self._peek(self.expr_lst_rsts_) == '":"': self._scan('":"') n = VAR else: self._rewind() expr_slst = self.expr_slst(R) v = {n or 0: expr_slst} while self._peek(self.expr_lst_rsts__) == 'COMMA': n = None COMMA = self._scan('COMMA') v['_'] = COMMA if self._peek(self.expr_lst_rsts) == 'VAR': VAR = self._scan('VAR') if self._peek(self.expr_lst_rsts_) == '":"': self._scan('":"') n = VAR else: self._rewind() expr_slst = self.expr_slst(R) v[n or len(v)] = expr_slst return ListValue(ParserValue(v)) def expr_slst(self, R): expr = self.expr(R) v = {0: expr} while self._peek(self.expr_slst_rsts) not in self.expr_lst_rsts__: expr = self.expr(R) v[len(v)] = expr return ListValue(ParserValue(v)) if len(v) > 1 else v[0] not_test_rsts_ = set(['AND', 'LPAR', 'QSTR', 'END', 'COLOR', 'INV', 'SIGN', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'BOOL', 'ID', 'RPAR', 'OR']) m_expr_chks = set(['MUL', 'DIV']) comparison_rsts = set(['LPAR', 'QSTR', 'RPAR', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'COMMA', 'GT', 'END', 'SIGN', 'ADD', 'FNCT', 'STR', 'VAR', 'EQ', 'ID', 'AND', 'INV', 'GE', 'BOOL', 'NOT', 'OR']) atom_rsts = set(['LPAR', 'QSTR', 'COLOR', 'INV', 'SIGN', 'NOT', 'ADD', 'NUM', 'BOOL', 'FNCT', 'STR', 'VAR', 'RPAR', 'ID']) not_test_chks = set(['NOT', 'INV']) u_expr_chks = set(['LPAR', 'COLOR', 'QSTR', 'NUM', 'BOOL', 'FNCT', 'STR', 'VAR', 'ID']) m_expr_rsts = set(['LPAR', 'SUB', 'QSTR', 'RPAR', 'MUL', 'DIV', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'COMMA', 'GT', 'END', 'SIGN', 'GE', 'FNCT', 'STR', 'VAR', 'EQ', 'ID', 'AND', 'INV', 'ADD', 'BOOL', 'NOT', 'OR']) expr_lst_rsts_ = set(['LPAR', 'QSTR', 'COLOR', 'INV', 'SIGN', 'VAR', 'ADD', 'NUM', 'BOOL', '":"', 'STR', 'NOT', 'ID', 'FNCT']) expr_lst_rsts = set(['LPAR', 'QSTR', 'COLOR', 'INV', 'SIGN', 'NOT', 'ADD', 'NUM', 'BOOL', 'FNCT', 'STR', 'VAR', 'ID']) and_test_rsts = set(['AND', 'LPAR', 'QSTR', 'END', 'COLOR', 'INV', 'SIGN', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'BOOL', 'ID', 'RPAR', 'OR']) u_expr_rsts_ = set(['LPAR', 'SUB', 'QSTR', 'RPAR', 'VAR', 'MUL', 'DIV', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'COMMA', 'GT', 'END', 'SIGN', 'GE', 'FNCT', 'STR', 'UNITS', 'EQ', 'ID', 'AND', 'INV', 'ADD', 'BOOL', 'NOT', 'OR']) u_expr_rsts = set(['LPAR', 'COLOR', 'QSTR', 'SIGN', 'ADD', 'NUM', 'BOOL', 'FNCT', 'STR', 'VAR', 'ID']) expr_rsts = set(['LPAR', 'QSTR', 'END', 'COLOR', 'INV', 'SIGN', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'BOOL', 'ID', 'RPAR', 'OR']) not_test_rsts = set(['LPAR', 'QSTR', 'COLOR', 'INV', 'SIGN', 'VAR', 'ADD', 'NUM', 'BOOL', 'FNCT', 'STR', 'NOT', 'ID']) comparison_chks = set(['GT', 'GE', 'NE', 'LT', 'LE', 'EQ']) expr_slst_rsts = set(['LPAR', 'QSTR', 'END', 'COLOR', 'INV', 'RPAR', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'BOOL', 'SIGN', 'ID']) a_expr_chks = set(['ADD', 'SUB']) a_expr_rsts = set(['LPAR', 'SUB', 'QSTR', 'RPAR', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'COMMA', 'GT', 'END', 'SIGN', 'GE', 'FNCT', 'STR', 'VAR', 'EQ', 'ID', 'AND', 'INV', 'ADD', 'BOOL', 'NOT', 'OR']) expr_lst_rsts__ = set(['END', 'COMMA', 'RPAR']) expr_lst_rsts_ = None ### Grammar ends. ################################################################################ expr_cache = {} def eval_expr(expr, rule, raw=False): # print >>sys.stderr, '>>',expr,'<<' results = None if not isinstance(expr, basestring): results = expr if results is None: if expr in rule[CONTEXT]: chkd = {} while expr in rule[CONTEXT] and expr not in chkd: chkd[expr] = 1 _expr = rule[CONTEXT][expr] if _expr == expr: break expr = _expr if not isinstance(expr, basestring): results = expr if results is None: if expr in expr_cache: results = expr_cache[expr] else: try: P = Calculator(CalculatorScanner()) P.reset(expr) results = P.goal(rule) except SyntaxError: if config.DEBUG: raise except Exception, e: log.exception("Exception raised: %s in `%s' (%s)", e, expr, rule[INDEX][rule[LINENO]]) if config.DEBUG: raise # TODO this is a clumsy hack for nondeterministic functions; # something better (and per-compiler rather than global) would be # nice if '$' not in expr and '(' not in expr: expr_cache[expr] = results if not raw and results is not None: results = to_str(results) # print >>sys.stderr, repr(expr),'==',results,'==' return results pyScss-1.1.5/scss/__init__.pyc0000644000076500000240000056166612107522123016723 0ustar kronuzstaff00000000000000ó ¾ Qc@sªdZddlZddlmZmZmZmZmZmZm Z m Z eZ eZ ede dZ e ZddlZddlZejeƒZyddlZWnek rÆddlZnXddlZddlZddlZddlZddlZddlmZyddlmZWnddlmZnXe Z!e Z"y ddl#m!Z!m"Z"m$Z$Wnek rej%d IJnXiZ&d d d d dddddddddddgZ'd d d d ddddgZ(idd 6dd6dd6dd6dd6Z)iidd 6dd 6d6idd6dd 6dd6dd d6dd!d6d"6idd6d#d6d$6idd6d#d6d%6iddd6d&6Z*iZ+iZ,xKe*j-ƒD]=\Z.Z/x.e/j-ƒD] \Z0Z1e.e+e06d?d@6dAdB6dCdD6dEdF6dGdH6dIdJ6dKdL6dMdN6d+dO6dPdQ6dRdS6dTdU6dVdW6dXdY6dZd[6d\d]6d^d_6d`da6dbdc6ddde6dfdg6dhdi6djdk6dldm6dndo6dpdq6drds6dtdu6dvdw6dxdy6dzd{6d|d}6d~d6d€d6d‚dƒ6d„d…6d†d‡6dˆd‰6dŠd‹6dŒd6dŽd6dd‘6d’d“6d”d•6d–d—6d˜d™6dšd›6dœd6dždŸ6d d¡6d¢d£6d¤d¥6d¦d§6d¨d©6dªd«6d¬d­6d®d¯6d°d±6d²d³6d´dµ6d¶d·6d¸d¹6dºd»6d¼d½6d¾d¿6dÀdÁ6dÂdÃ6d€dÄ6dÅdÆ6dÇdÈ6dÉdÊ6dËdÌ6dÍdÎ6dÏdÐ6dÑdÒ6dÓdÔ6dÕdÖ6d×dØ6dÙdÚ6dÛdÜ6dÝdÞ6dßdà6dádâ6dãdä6dådæ6dçdè6dédê6dëdì6dídî6dïdð6dñdò6dódô6dõdö6d÷dø6dùdú6dûdü6dýdþ6dÿd6dd6dd6dd6dd6d d 6d d 6d d6dd6dd6dd6dd6dd6dd6dd6dd6dd 6d!d"6d#d$6d%d&6d'd(6d)d*6d+d,6d-d.6d/d06d1d26d3d46d5d66d7d86d9d:6d;d<6Z2id=d>6d?d@6dAdB6dCdD6dEdF6dGdH6dIdJ6Z3e4dK„e3j-ƒDƒƒZ5ej6dLj7e8ej9e3ƒƒƒZ:ej6dLj7e8ej9e5ƒƒƒZ;iZ<idMdN6Z=iedO6edP6edQ6edR6edS6edT6e dU6e dV6d=dW6d?dX6dAdY6dCdZ6dEd[6dGd\6dId]6d^d_6d`da6Z>iej?db6dcdd6dcde6dcdf6dNdg6dNdh6Z@diZAej6djejBƒZCej6dkeAejBƒZDej6dkeAdlejBƒZEej6dmejFƒZGej6dnejFƒZHe4do„e2j-ƒDƒƒZIx¢e2j-ƒD]”\ZJZKeGjLdpeKƒjMƒZNeHjLdq„eKƒZOeHjLdr„eKƒZPeQeNeJeOePgdseRƒZ0e0eIeJZd?Zd@ZdAZi e4e e!ej"d•dƒjtdBƒƒƒƒdC6e4e e!ej"d•dƒjtdBƒƒƒƒdD6e4e e!ej"d•dƒjtdBƒƒƒƒd86e4e e!ej"d•dƒjtdBƒƒƒƒdE6e4e e!ej"d•dƒjtdBƒƒƒƒdF6e4e e!ej"d•dƒjtdBƒƒƒƒdG6e4e e!ej"d•dƒjtdBƒƒƒƒdH6e4e e!ej"d•dƒjtdBƒƒƒƒdI6e4e e!ej"d•dƒjtdBƒƒƒƒdJ6e4e e!ej"d•dƒjtdBƒƒƒƒdK6e4e e!ej"d•dƒjtdBƒƒƒƒdL6e4e e!ej"d•dƒjtdBƒƒƒƒdM6Z#dN„Z$dO„Z%dP„Z&e e dQ„Z'dRdS„Z(e dT„Z)dU„Z*dV„Z+dWe‹fdX„ƒYZ,dYe‹fdZ„ƒYZ-d[e-fd\„ƒYZ.d]e-fd^„ƒYZ/d_e-fd`„ƒYZ0dae-fdb„ƒYZ1dce-fdd„ƒYZ2dee2fdf„ƒYZ3i–eÙdg6eÙdh6eÚdi6eÚdj6eÚdk6e×dl6eÝdm6eÝdn6eÞdo6eÞdp6eÞdq6eÛdr6eÜds6eßdt6eàdu6eàdv6eàdw6eádx6eády6eádz6eád{6eád|6eìd}6eìd~6eìd6eìd€6eìd6eëd‚6eëdƒ6eíd„6eîd…6eäd†6eäd‡6eçdˆ6eçd‰6eèdŠ6eéd‹6eñdŒ6eòd6eÇdŽ6eÈd6eÉd6eÄd‘6eÍd’6eÎd“6eÏd”6eÐd•6e¨d–6e¨d—6e¨d˜6e©d™6e©dš6e©d›6e«dœ6e¬d6e­dž6e®dŸ6e¯d 6e¯d¡6e°d¢6e³d£6e´d¤6eµd¥6e¶d¦6e¸d§6e¹d¨6eºd©6e°dª6e±d«6e²d¬6e»d­6e»d®6e¥d¯6e¢d°6e£d±6e£d²6e¦d³6ed´6e dµ6e¡d¶6e¡d·6ežd¸6e¤d¹6e¼dº6e½d»6e¾d¼6e¿d½6e¿d¾6eÀd¿6eÁdÀ6eÂdÁ6edÂ6edÃ6edÄ6edÅ6edÆ6edÇ6edÈ6edÉ6e dÊ6e dË6eódÌ6eôdÍ6eõdÎ6eödÏ6e÷dÐ6eødÑ6eúdÒ6eýdÓ6eþdÔ6eúdÕ6eùdÖ6eûd×6eûdØ6eüdÙ6eüdÚ6eÿdÛ6eÿdÜ6e%dÝ6e&dÞ6e'dß6e'dà6e'dá6e'dâ6e'dã6e'dä6e(då6e(dæ6e)dç6e)dè6e dé6e dê6edë6edì6edí6edî6edï6e$dð6edñ6e dò6e dó6e dô6e-j4e“j5ƒdõ6e-j4e“j6ƒdö6e-j4e“j7ƒd÷6e-j4e8ƒdø6e-j4e9ƒdù6e-j4e“j:ƒdú6e-j4e“j;ƒdû6edü6Z<xe'D]Z=e*e<e=dýeãdÿ„Z?e" r<de@fd„ƒYZ$de‹fd„ƒYZ"nde"fd„ƒYZAde‹fd„ƒYZBdeAfd „ƒYZCd eBfd „ƒYZDiZEeØd „ZFdS( s< pyScss, a Scss compiler for Python @author German M. Bravo (Kronuz) @version 1.1.5 @see https://github.com/Kronuz/pyScss @copyright (c) 2012-2013 German M. Bravo (Kronuz) @license MIT License http://www.opensource.org/licenses/mit-license.php pyScss compiles Scss, a superset of CSS that is more powerful, elegant and easier to maintain than plain-vanilla CSS. The library acts as a CSS source code preprocesor which allows you to use variables, nested rules, mixins, andhave inheritance of rules, all with a CSS-compatible syntax which the preprocessor then compiles to standard CSS. Scss, as an extension of CSS, helps keep large stylesheets well-organized. It borrows concepts and functionality from projects such as OOCSS and other similar frameworks like as Sass. It's build on top of the original PHP xCSS codebase structure but it's been completely rewritten, many bugs have been fixed and it has been extensively extended to support almost the full range of Sass' Scss syntax and functionality. Bits of code in pyScss come from various projects: Compass: (c) 2009 Christopher M. Eppstein http://compass-style.org/ Sass: (c) 2006-2009 Hampton Catlin and Nathan Weizenbaum http://sass-lang.com/ xCSS: (c) 2010 Anton Pawlik http://xcss.antpaw.org/docs/ iÿÿÿÿN(t BUILD_INFOtPROJECTtVERSIONtREVISIONtURLtAUTHORt AUTHOR_EMAILtLICENSEs (tdeque(tStringIO(t locate_blockstScannert NoMoreTokenss5Scanning acceleration disabled (_speedups not found)!temtextpxtcmtmmtintpttpctdegtradgradtmststhztkhzt%i idg*@gð?tsizeg$@gffffff9@iHitlengthg@@ttimetfreqtanys#f0f8fft aliceblues#faebd7t antiquewhites#00fffftaquas#7fffd4t aquamarines#f0fffftazures#f5f5dctbeiges#ffe4c4tbisques#000000tblacks#ffebcdtblanchedalmonds#0000fftblues#8a2be2t blueviolets#a52a2atbrowns#deb887t burlywoods#5f9ea0t cadetblues#7fff00t chartreuses#d2691et chocolates#ff7f50tcorals#6495edtcornflowerblues#fff8dctcornsilks#dc143ctcrimsontcyans#00008btdarkblues#008b8btdarkcyans#b8860bt darkgoldenrods#a9a9a9tdarkgrays#006400t darkgreens#bdb76bt darkkhakis#8b008bt darkmagentas#556b2ftdarkolivegreens#ff8c00t darkoranges#9932cct darkorchids#8b0000tdarkreds#e9967at darksalmons#8fbc8ft darkseagreens#483d8bt darkslateblues#2f4f4ft darkslategrays#00ced1t darkturquoises#9400d3t darkviolets#ff1493tdeeppinks#00bffft deepskyblues#696969tdimgrays#1e90fft dodgerblues#b22222t firebricks#fffaf0t floralwhites#228b22t forestgreens#ff00fftfuchsias#dcdcdct gainsboros#f8f8fft ghostwhites#ffd700tgolds#daa520t goldenrods#808080tgrays#008000tgreens#adff2ft greenyellows#f0fff0thoneydews#ff69b4thotpinks#cd5c5ct indianreds#4b0082tindigos#fffff0tivorys#f0e68ctkhakis#e6e6fatlavenders#fff0f5t lavenderblushs#7cfc00t lawngreens#fffacdt lemonchiffons#add8e6t lightblues#f08080t lightcorals#e0fffft lightcyans#fafad2tlightgoldenrodyellows#90ee90t lightgreens#d3d3d3t lightgreys#ffb6c1t lightpinks#ffa07at lightsalmons#20b2aat lightseagreens#87cefat lightskyblues#778899tlightslategrays#b0c4detlightsteelblues#ffffe0t lightyellows#00ff00tlimes#32cd32t limegreens#faf0e6tlinentmagentas#800000tmaroons#66cdaatmediumaquamarines#0000cdt mediumblues#ba55d3t mediumorchids#9370dbt mediumpurples#3cb371tmediumseagreens#7b68eetmediumslateblues#00fa9atmediumspringgreens#48d1cctmediumturquoises#c71585tmediumvioletreds#191970t midnightblues#f5fffat mintcreams#ffe4e1t mistyroses#ffe4b5tmoccasins#ffdeadt navajowhites#000080tnavys#fdf5e6toldlaces#808000tolives#6b8e23t olivedrabs#ffa500toranges#ff4500t orangereds#da70d6torchids#eee8aat palegoldenrods#98fb98t palegreens#afeeeet paleturquoises#db7093t palevioletreds#ffefd5t papayawhips#ffdab9t peachpuffs#cd853ftperus#ffc0cbtpinks#dda0ddtplums#b0e0e6t powderblues#800080tpurples#ff0000treds#bc8f8ft rosybrowns#4169e1t royalblues#8b4513t saddlebrowns#fa8072tsalmons#f4a460t sandybrowns#2e8b57tseagreens#fff5eetseashells#a0522dtsiennas#c0c0c0tsilvers#87ceebtskyblues#6a5acdt slateblues#708090t slategrays#fffafatsnows#00ff7ft springgreens#4682b4t steelblues#d2b48cttans#008080tteals#d8bfd8tthistles#ff6347ttomatos#40e0d0t turquoises#ee82eetviolets#f5deb3twheats#fffffftwhites#f5f5f5t whitesmokes#ffff00tyellows#9acd32t yellowgreens//s ^doubleslash^s/*s ^bigcopen^s*/s ^bigcclose^t:s ^doubledot^t;s ^semicolon^t{s^curlybracketopen^t}s^curlybracketclosed^ccs!|]\}}||fVqdS(N((t.0tktv((s1/Users/kronuz/Development/pyScss/scss/__init__.pys st|s :0is $BUILD_INFOs$PROJECTs$VERSIONs $REVISIONs$URLs$AUTHORs $AUTHOR_EMAILs$LICENSEs$__doubleslashs $__bigcopens $__bigccloses $__doubledots $__semicolons$__curlybracketopens$__curlybracketcloseds background:sbg:sbackground-color:sbgc:t verbosityitcompresstcompress_short_colorstcompress_reverse_colorst short_colorstreverse_colorsts[ \t\r\f\v]*\n[ \t\r\f\v]*s\n.+s[ \t\r\f\v]*\ns.(?Css#\1\2\3cCsGdt|jdƒdƒt|jdƒdƒt|jdƒdƒfS(Nsrgb(%d, %d, %d)iiii(tinttgroup(tm((s1/Users/kronuz/Development/pyScss/scss/__init__.pytGscCsGdt|jdƒdƒt|jdƒdƒt|jdƒdƒfS(Nsrgba(%d, %d, %d, 1)iiii(R½R¾(R¿((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRÀHstkeys(?i(tNonetlent RULE_VARStsetRÇRÊRËRÌRÍRÎtFalseRÏtlisttitemstupper(truletkwargsR³R´((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt spawn_ruleÉs        cs‡fd†}|S(Ncs'tjr‡‡fd†}|SˆSdS(Ncsutjˆkrdtjƒ}ˆ||Ž}tjƒ}tjˆjdƒtˆjc||7<|Sˆ||ŽSdS(Ni(tconfigt VERBOSITYRt profilingt setdefaultt func_name(targsRÚtt1trestt2(tleveltfunc(s1/Users/kronuz/Development/pyScss/scss/__init__.pytwrapperÝs  (RÜRÝ(RæRç(Rå(Ræs1/Users/kronuz/Development/pyScss/scss/__init__.pyt _print_timingÛs  ((RåRè((Rås1/Users/kronuz/Development/pyScss/scss/__init__.pyt print_timingÚscCsÓ|jdƒpg}|rÏg}|jdƒ}y‚x{tr°xR|jdƒ|jdƒkry|d|jdƒ}Wq?tk rŒPq?Xq?W|j|ƒ|jdƒ}q6WWntk rÅnX|}n|S(Nt,it(t)(tsplittpoptTruetcountt IndexErrortappend(tparamst final_paramstparam((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt split_params s" !     cCsJ|rF|ddkrF|d|dkrF|dd!}t|ƒ}n|S(Nit"t'iÿÿÿÿi(R÷Rø(tunescape(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pytdequotes* cCs>x7|r9|ddkr9|ddkr9|dd!}qW|S(NiRëiÿÿÿÿRìi((R((s1/Users/kronuz/Development/pyScss/scss/__init__.pytdepar&s)cCsˆ|jtƒ\}}}|tkrZ|jdƒ}yt|ƒ}Wq`tk rVq`Xn|}tjd|ƒ}|jƒ}||fS(Ns ;s (t partitiont SEPARATORtstripR½t ValueErrort _nl_num_retsub(tselproptlinenot_linenot_sep((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_strip_selprop0s   cCst|dƒ\}}|S(N(RRÑ(Rt_((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_strip@sccs¡d}d}d}d}t}d}d}}} } d} } xitj|ƒD]X} | jdƒ}||}|dk r“||kr¨d}q¨qP|dkr¨|}qP|dkrÑ|d7}d}|d} qP|dkrê|d8}qP| rP| rP|dkrÅ|dkr¸|dkr9||ddkr9t}q¸|} |dk rgt|||!ƒrg|}n| |kr¯t|| |!|ƒ\}}|r¦||dfVn|} nd}n|d7}q¨|d krs|dkr¥|d8}|dkrp|sd|} t||| !|ƒ\}}|| d| !jƒ}|rI|||fVn| d}} } d}nt}qpq¥q¨|dkr¨|d krî|}| |kråt|| |!|ƒ\}}|rÐ||dfVn|d}} } nd}q¥|d kr5|dk r"t|||!ƒr"|}nd}|d} q¥|d kr¥|dk rst|||!ƒrs|}|d}q¢|dkr¢t|| |!ƒr¢|d}q¢q¥q¨qPqPW|dkrM|sMt||| !|ƒ\}}|| djƒ}|r|||fVn|rt d |ƒ‚qJ|r7t d|ƒ‚qJt d|ƒ‚qMn|| }xC|j d ƒD]2}t||ƒ\}}|rg||dfVqgqgWdS(sÁ For processing CSS like strings. Either returns all selectors (that can be "smart" multi-lined, as long as it's joined by `,`, or enclosed in `(` and `)`) with its code block (the one between `{` and `}`, which can be nested), or the "lose" code (properties) that doesn't have any blocks. threshold is the number of blank lines before selectors are broken into pieces (properties). iR÷RøRëiRìR°t#R±R¯Rês s4Missing closing parenthesis somewhere in block: '%s's/Missing closing string somewhere in block: '%s'sBlock never closed: '%s'N(R÷Rø( RÑRÕt _blocks_retfinditertstartRïRRRþt ExceptionRí(tcodestrRtpartinstrtdepthtskiptthintitinittsafetloseR tendR¿tct _propertyt _selectorst_codestrtlosestr((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR Es¬                                      tScsscBs·eZdZd-d-d-d-d„Zd„Zd„Zd„Zd-d„Zd-d-d-d-d„Z e Z d-d„Z d„Z d „Z d-d-d „Zd-d-ed „Zed ƒd „ƒZedƒd„ƒZedƒd„ƒZedƒd„ƒZedƒd„ƒZedƒd„ƒZedƒd„ƒZedƒd„ƒZedƒd„ƒZedƒd„ƒZedƒd„ƒZedƒd„ƒZedƒd„ƒZedƒd„ƒZedƒd„ƒZ edƒd„ƒZ!ed ƒd„ƒZ"ed ƒd „ƒZ#ed ƒd!„ƒZ$ed ƒd-d"„ƒZ%d-e&d#d$d%ed&„Z'd-d-e&d#d'd%d-d(„Z(d)„Z)d*„Z*ed+„Z+ed ƒd,„ƒZ,RS(.tselfcCsH|r|d|_n d|_||_||_||_|jƒdS(NRÃRÂ(tsuper_selectort _scss_varst _scss_optst _scss_filestreset(Rt scss_varst scss_optst scss_filesR ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt__init__´s    cCs)|jp i}td„|jƒDƒƒS(NcssV|]L\}}|r|jdƒ sD|jdƒr|djƒr||fVqdS(t$iN(t startswithtisupper(R²R³R´((s1/Users/kronuz/Development/pyScss/scss/__init__.pys Às(R%tdictR×(RR%((s1/Users/kronuz/Development/pyScss/scss/__init__.pytget_scss_constants¾scCs)|jp i}td„|jƒDƒƒS(NcssW|]M\}}|r|jdƒ pA|jdƒoA|djƒ r||fVqdS(R)iN(R*R+(R²R³R´((s1/Users/kronuz/Development/pyScss/scss/__init__.pys Äs(R%R,R×(RR%((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt get_scss_varsÂscCs+tƒ|_g|_i|_i|_dS(N(R tchildrentrulest_rulestparts(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pytcleanÆs   cCsrttdƒrtjƒng|_tjƒ|_|jdk rY|jj |jƒnt jƒ|_ |j dk r|j j |j ƒni|_ g|_xItjƒD];\}}||j krÚ|jj|ƒn||j |i2s...tfileidRtcontexttoptionstindexiRÂiÿs (IE exceeded!)sKMaximum number of supported selectors in Internet Explorer (4095) exceeded!t debug_infosˆscss'|]}|jƒr|jƒVqdS(N(Rþ(R²R((s1/Users/kronuz/Development/pyScss/scss/__init__.pys Šscss'|]}|jƒr|jƒVqdS(N(Rþ(R²R((s1/Users/kronuz/Development/pyScss/scss/__init__.pys ŒsRÂcss'|]}|jƒr|jƒVqdS(N(Rþ(R²R((s1/Users/kronuz/Development/pyScss/scss/__init__.pys ‘s( t _spaces_reRt isinstancet basestringRíRÔRüRþtaddR:tdiscardtjointsorted( RRtextra_selectorst extra_parentstparentst selectorsRÁtchildRtparent((s1/Users/kronuz/Development/pyScss/scss/__init__.pytnormalize_selectorsqs4      '  *c s0t|tƒrd|kr||krlxÕt|tƒrh||krh||}||kr_Pn|}q*Wqi‰xf|jƒD]X\}}x?t|tƒrÌ||krÌ||} | |krÃPn| }qŽW|ˆ|kr|j#||||||||| ƒ q„| dk rr| d6krr|p0g| g} |j$d7| d8|t<|j%|||||| ƒq„| dkr›|t&j'||dfƒq„|dkr„|j(||||||||| ƒ q„q| dkr|j)||||||||| ƒ q|j*dƒrP| |t<|j%|||||p:d |d9 d:|ƒq|dkr|j(||||||||| ƒ qqWdS(?Ns@returnt+s @include iRëR®Rìt=s@mixins @prototype i t@RÂis@warns@prints@raws @dump_contexts @dump_optionss@debugt1ttruetttyestytont0tfalseRCtnoRftofft undefinedisDebug mode is %stOntOffs@options@contents@imports@extendcss|]}|jƒVqdS(N(Rþ(R²tp((s1/Users/kronuz/Development/pyScss/scss/__init__.pys sRêR{s @functions@includes@ifs @else if s@elses@fors@eachs @variabless@varss@medias {R±iÿÿÿÿt-(RstrueRŸsyesR¡son(R£sfalseRCsnoRfsoffR§(s@mixins @function(s @variabless@vars(+R RÆRÉR*RGtreplaceRÿRíRÑtlowert calculateRÈRQtwarnRúRŠtsyststderrtreprtinfoRþRÜtDEBUGt_settle_optionst _do_contentt _do_importR“R:R€t _do_functionst _do_includet_do_ift_do_elset_do_fort_do_eacht_get_variablest constructR•RËRòt _nest_rulest_get_propertiestendswith(RRÙt p_selectorst p_parentst p_childrentscopetmediatc_linenot c_propertyt c_codestrtcodetnametrett_media((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR•Þs¤ *    #              " . . .  ,.   .'....(  + ( 1 i c  Cs¬x¥| jdƒD]”} | jddƒdgd \} } | jƒjƒ} | jƒ} | r| jƒdkrxd} n| jƒdkr“d} n| |t| "sNs\Rt/csmdˆd|}|ˆtkr@tˆt|ˆƒˆ|9ss -positions-spacings-repeatR)R«tspritessè @import "compass/utilities/sprites/base"; // All sprites should extend this class // The %(map_name)s-sprite mixin will do so for you. #{$%(map_name)s-sprite-base-class} { background: $%(map_name)s-sprites; } // Use this to set the dimensions of an element // based on the size of the original image. @mixin %(map_name)s-sprite-dimensions($name) { @include sprite-dimensions($%(map_name)s-sprites, $name); } // Move the background position to display the sprite. @mixin %(map_name)s-sprite-position($name, $offset-x: 0, $offset-y: 0) { @include sprite-position($%(map_name)s-sprites, $name, $offset-x, $offset-y); } // Extends the sprite base class and set the background position for the desired sprite. // It will also apply the image dimensions if $dimensions is true. @mixin %(map_name)s-sprite($name, $dimensions: $%(map_name)s-sprite-dimensions, $offset-x: 0, $offset-y: 0) { @extend #{$%(map_name)s-sprite-base-class}; @include sprite($%(map_name)s-sprites, $name, $dimensions, $offset-x, $offset-y); } @mixin %(map_name)s-sprites($sprite-names, $dimensions: $%(map_name)s-sprite-dimensions) { @include sprites($%(map_name)s-sprites, $sprite-names, $%(map_name)s-sprite-base-class, $dimensions); } // Generates a class for each sprited image. @mixin all-%(map_name)s-sprites($dimensions: $%(map_name)s-sprite-dimensions) { @include %(map_name)s-sprites(%(sprites)s, $dimensions); } R RÃ(tcallableRÜRR‚RòRñRtglobtnormpathRôR¬t StringValuet BooleanValueRÕt NumberValuettuplet _sprite_mapRÈ(RRÙRÃRÄRÅRÆRÇRÈRÉRÊRËRÌtfilest glob_pathRßR R R RþRft sprite_mapRÍ((RÚRÙR s1/Users/kronuz/Development/pyScss/scss/__init__.pyRûs06  $!c Cs| dkred|tkr;tjd|t|tƒn|tjdtƒ } |djƒ} nt} | r|j| |t |t|ƒ} t | sÅt | t ƒrË| dksÅt j| ƒrËtn| ƒ} | r| |t<|j||||||ƒn| |td#sRÂRRÑRERFR†RÒRÓRÇR(R¿RÐRÆR•R“RÈRÉRïR‰RüRÔRíRR¬RR‚R€RÛR9RÕt appendleft(RRÙRÃRÄRÅRÆRÇRÈRÉRÊt c_selectorsRt c_parentstbetter_selectorst c_selectort p_selectorR…RÛ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRÀs4 #     #Yc Cs^d }xQ|jjƒD]@\}}|jdƒ\}}}|jdƒ}tƒ} t} x|D]} || krwq_nxô|jdƒD]ã} | |} }|j| |ƒ}|rÉ| |} ||}n|j| |ƒ}|rú| | } || }n| r‡|r‡|dd krdnd }d }t j |||| | ƒ}| |krj| j |ƒt } qjq‡q‡Wq_W| r”|pg}|j |ƒn| r|j|| ƒ} | |krì|j|=|jj| gƒ|j| j |ƒntƒ}x/|pgD]!}||t<|j |tƒqWx,|D]!}| |t<|tj|ƒq.WqqW|S( s† Link with a parent for the current child rule. If parents found, returns a list of parent rules to the child s extends RêiRR RtR®s (?tcommentss/* file: %s, line: %s */s\\\1sU@media -sass-debug-info{filename{font-family:file\:\/\/%s}line{font-family:\00003%s}}c3s"|]}dˆj|fVqdS(s%s%sN(R (R²R(R(s1/Users/kronuz/Development/pyScss/scss/__init__.pys ;sR¶s /* file: s */s/* vars:s = s*/(RÑRÔRÕttextwrapt TextWrapperR5tcompilet wordsep_retwrapRÅRËRÊRÐRRïRíRÒRÎRÍtrsplitR*t_escape_chars_reRRÉRSRÄRÈR×t_print_properties(#RR0RÆRNRORPRQRHtopen_selectorstskip_selectorst old_selectorst open_mediat old_mediat old_propertyRYR]R^tresultRÙR†RÇt_tbRRRRaRWRt real_filenamet real_linenotsass_debug_infot _filenametselectorR³R´((Rs1/Users/kronuz/Development/pyScss/scss/__init__.pyRMÞsÖ          )    .        +    &6    RÂc Csl|dkr<tjdtƒ}tjdƒ|_|j}n|dkrTdg}n|dkrltƒ}nd} xó|D]ë\} } } | dk rÏ|rº|||j || ƒƒ} n| d|| } n| } d| kr| j ddƒj ddƒj ƒ} | |krqyqn|d| kry| |d<|j | ƒ| |d<| || d |7} qyqyW| S( NRRs (?<=,)(\s*)RÂR®s!defaults RÃiR¯( RÑRURVRÕR5RWRXRYRÔRR¬RþR(RRÒRÆRbRNRORdRQRYRcRR*RÐtproperty((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR\`s2         $     c Cs¾|}tj|ƒrId|krId|krId|krId|krI|St|ƒ}||t<||t<|j||||ƒ}t||tƒ}|dkrº|j ||||ƒ}n|S(Ns- s and s or snot ( t _skip_word_reRRÖRÈRÉRt eval_exprRïRÑR“(Rt _base_strRERFRÙtbetter_expr_str((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR®}s?    cs‡‡‡‡‡fd†}|S(Ncsv|jdƒ}|}t|ˆƒ}|dkrKˆj|ˆˆˆƒ}n'ˆrftt|ƒƒ}n t|ƒ}|S(Ni(R¾RlRÑR“RúRb(Rct_group0RmRn(RRÙRERŒRF(s1/Users/kronuz/Development/pyScss/scss/__init__.pyt__calculate_expr‘s  ((RRERFRÙRŒt_Scss__calculate_expr((RRÙRERŒRFs1/Users/kronuz/Development/pyScss/scss/__init__.pyt_calculate_exprs cCsDt|ƒ}d|kr|Stj|j||||ƒ|ƒ}|S(Ns#{(Rbt _expr_glob_reRRr(RRRERFRÙRŒ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR s   $cCs±|jjddƒrdpd}|jj|ddƒrOtjd|ƒ}n|jj|ddƒr€tjd„|ƒ}n|r­tjd |ƒ}tjd |ƒ}n|S( NR·it compress_RÂRºs#\1\2\3R»cSst|jdƒjƒS(Ni(t_reverse_colorsR¾R­(R¿((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRÀ¯sR£Rt(R&RSt_short_color_reRt_reverse_colors_ret_zero_units_ret_zero_re(RRR·((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRT§s!N(-t__name__t __module__R¿RÑR(R-R.R3R$R_RWRKRyRzR‰RÕR“RéRLR•RµR¸R¹R¶R·RûRºR»R¼R½R¾RÁRÀRERMRNRORPRïRMR\R®RrRRT(((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR°sP    #2 1  &(^ 66 WO ( /'F;  ‚   (tImaget ImageDrawcCs½t|tƒrNt|jƒƒ}|jddƒ}|djd„|DƒƒSt|tƒr†dt|dƒjdƒjdƒ}|St|t ƒr£|rŸd Sd S|dkr³dSt |ƒS( NRRÂRÃcss-|]#\}}|dkrt|ƒVqdS(RN(RŠ(R²RfR´((s1/Users/kronuz/Development/pyScss/scss/__init__.pys Òss%0.03fiR£RtRžR¤( R}R,R‚R×RSRR troundtrstripRRÑRb(tnumRRO((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRŠÎs% cCsat|ttfƒrt|ƒSt|ƒ}|rS|ddkrSt|d ƒdSt|ƒSdS(NiÿÿÿÿRgY@(R}R R½RŠ(R€((s1/Users/kronuz/Development/pyScss/scss/__init__.pytto_floatÝs   cCsPt|dd!dƒt|dd!dƒt|dd!dƒt|dd!dƒfS(Niiiiii (R½(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRÀèscCs@t|dd!dƒt|dd!dƒt|dd!dƒdfS(Niiiiigð?(R½(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRÀéscCsTt|dddƒt|dddƒt|dddƒt|dddƒfS(Niiiii(R½(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRÀêscCsCt|dddƒt|dddƒt|dddƒdfS(Niiiigð?(R½(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRÀëscCstjdd|ƒS(Ns(["'])s\\\1(R5R(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pytescapeïscCstjdd|ƒS(Ns\\(['"])s\1(R5R(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRùóstrgbcCst|||d|ƒS(Ngð?(t_rgba(trtgtbttype((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_rgbûstrgbacCs)t|ƒt|ƒt|ƒt|ƒf}gtdƒD]}||jdksv||jdkr‡||jdkr‡||jdn<||jdkr dn#||jdkr¹dn ||j^q7}||djdkrèdn#|djdkrdn |djg7}||g7}t|ƒS( NiRiigào@giÿgð?(RR"tunitRÐt ColorValue(R…R†R‡RÙRˆRRtcol((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR„ÿs *ŸF cCsŒt|ƒj}|dk r*t|ƒjn|d}t|d ƒ}||dkrYdn|dkrkdn|g7}||g7}t|ƒS(Niigigð?(RŒRÐRÑRRÖ(tcolorRÙRˆR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt _color_type s %1 cCst|ddƒS(Ngð?Rƒ(R(RŽ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_rgb2scCst||dƒS(NRŠ(R(RŽRÙ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_rgba2scCst|ddƒS(Ngð?thsl(R(RŽ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_hsl2scCst||dƒS(Nthsla(R(RŽRÙ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_hsla2"scCsUt|ƒj}tdt|ddƒt|dƒt|dƒt|dƒfƒS(Ns#%02X%02X%02X%02Xiiÿiii(RŒRÐRR~(RŽR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt _ie_hex_str&sR’cCst|||d|ƒS(Ngð?(t_hsla(thRtlRˆ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_hsl+sR”c CsÂt|ƒt|ƒt|ƒt|ƒf}|djdkrm|djdkrm|djdkrm|dn|djddg}|ggtddƒD]]}||jdksÚ||jdkrç||jdkrç||jn||jd^q›D]0}|dkrdn|dkr&dn|^qü7}||g7}gtj|d|d dkrfd n|d |ddkrƒd n|dƒD]}|d ^qŽ|d |g}t|ƒ}|S( NiRig€v@igY@ggð?igé !çýÿï?gào@i(RR‹RÐR"tcolorsyst hls_to_rgbRŒ( R˜RR™RÙRˆRRRtcl((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR—/s*[¥ r cCsst|ƒ}|j}|dkr'dn t|ƒj|dkrEdn t|ƒj|dkrcdn t|ƒj|dkrdn t|ƒjg}gtdƒD]]}|dk rÙ||dk rÙ|||||ƒn!||dk ró||n||^q }d}gtdƒD]D}||dkr2dn%||||krP||n||^q}t|ƒ|_|S(Nigào@gð?ig(gào@gào@gào@gð?(RŒRÐRÑRR"R(topRŽR…R†R‡RÙRR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt __rgba_op?s  $pWcCsttj|ddd|ƒS(Ni(RŸtoperatort__add__(RŽtamount((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_opacifyQscCsttj|ddd|ƒS(Ni(RŸR t__sub__(RŽR¢((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_transparentizeUsc Csút|ƒ}|j}|dkr'dn t|ƒ}|dkrEdn t|ƒ}|dkrcdn t|ƒ}|dkrdn |jd|dkrdn1|jdkrÈ|jdkrÈ|jdn|j|dkràdn1|jdkr |jdkr |jdn|jg}ttj|dd|dd|ddƒƒ\}}}|||f}gtdƒD]‰}||dkr‹d nj||dkr¡d nT|dk rÔ||dk rÔ|||||ƒn!||dk rî||n||^qo}|ddd |d #7f007f mix(#f00, #00f, 25%) => #3f00bf mix(rgba(255, 0, 0, 0.5), #00f) => rgba(63, 0, 191, 0.75) gà?igigð?iiiÿÿÿÿg@iN(RŒRÐRÑRtmergeR"(tcolor1tcolor2tweighttc1tc2RªtwRÙtw1tw2tqR…RŽR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_mixÀs/!*4 >cCst|ƒj}t|dƒS(Ni(RŒRÐR(RŽR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_red scCst|ƒj}t|dƒS(Ni(RŒRÐR(RŽR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_green scCst|ƒj}t|dƒS(Ni(RŒRÐR(RŽR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_blue scCst|ƒj}t|dƒS(Ni(RŒRÐR(RŽR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_alpha scCs|t|ƒj}tj|dd|dd|ddƒ\}}}t|dƒ}itjddƒd6dd6|_|S(Nigào@iig€v@RR(RŒRÐR›R¦Rt_units_weightsRStunits(RŽRR˜R™RRÍ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_hue s 6#cCsxt|ƒj}tj|dd|dd|ddƒ\}}}t|ƒ}itjddƒd6dd6|_|S(Nigào@iiRR(RŒRÐR›R¦RRÌRSRÍ(RŽRR˜R™RRÍ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt _saturation s 6 #cCsxt|ƒj}tj|dd|dd|ddƒ\}}}t|ƒ}itjddƒd6dd6|_|S(Nigào@iiRR(RŒRÐR›R¦RRÌRSRÍ(RŽRR˜R™RRÍ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt _lightness' s 6 #cGst|ƒdkr t|dtttfƒrBt|dƒjƒSt|dttfƒr g}t|dj ƒ}xŽ|D]†}|j ƒ}|j dƒrÖt|dj dƒƒ\}}|j ƒ}|j ƒ}n|j ƒ\}}|jt|ƒ|fƒq{W|Sng}g}t}x|D]û}t|tƒrºxã|jƒD]l\} }t|tƒrŽ|rx|jdƒn|j|ƒt}qGt|tƒrG|j|ƒt}qGqGWq%t|tƒrõ|rß|jdƒn|j|ƒt}q%t|tƒr%|jt|ƒƒt}q%q%W|r:|jdƒn|t|ƒ }|ritd„|Dƒƒ} ntd„|Dƒƒ} g|D]1}|o´|jdkr®|j | n|j ^q†}d|d\ scss6|],}|r*|jdkr$|ndp-dVqdS(RN(R‹RÑ(R²R((s1/Users/kronuz/Development/pyScss/scss/__init__.pys ^ sRgð?(RÒR}RÖRR&RëRR~RöRÐRþR*RRíRòRRÕR×RŒRÑRïRtmaxR‹RÔR"tzip(t percentagesRát color_stopstcolorsRŽRRtstopst prev_colorRt max_stopsRR RRÓtstridetj((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt __color_stops/ s~          >       2!  %cGs˜t|ƒdkrGt|dtttfƒrGt|dƒjƒ}ntt|Œ}djg|D]"\}}dt |ƒ|f^qcƒ}t |ƒS(Niis, scolor-stop(%s, %s)( RÒR}RÖRR&RëRÛRïRRŠR(RáRÔRRRÍ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_grad_color_stopsy s .8cCstdd||ƒS(Niÿÿÿÿid(t__grad_position(tradialRÔ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt__grad_end_position scCs’ynt||dƒ}|rm|jdkrm|dksZ|dksZ|t|ƒdkrmtjd|ƒnWntk rt|ƒ}nX|S(NiRiÿÿÿÿisTWebkit only supports pixels for the start and end stops for radial gradients. Got %s(RR‹RÒRQR¯Rñ(RGRãRÞRÔRÖ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRÝ… sC cGs"tt|Œ}ttt|ƒƒS(N(RÛRÕRRß(RÔ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_grad_end_position scGs˜t|ƒdkrGt|dtttfƒrGt|dƒjƒ}ntt|Œ}djg|D]"\}}d|t |ƒf^qcƒ}t |ƒS(Niis, s%s %s( RÒR}RÖRR&RëRÛRÕRRŠR(RáRÔRRRÍ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt _color_stops” s .8cGs˜t|ƒdkrGt|dtttfƒrGt|dƒjƒ}ntt|Œ}djg|D]"\}}d|t |ƒf^qcƒ}t |ƒS(Niis, s%s %s( RÒR}RÖRR&RëRÛRïRRŠR(RáRÔRRRÍ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_color_stops_in_percentagesœ s .8cCsèxá|D]Ù}t|tttfƒr1|g}n$t|tttfƒr|}nqd}t}x?|D]7}t|t ƒr‡t }Pqht|tƒrh|}qhqhW|r¯qn|dk r¿|SxdD]}||krÆ|SqÆWqWdS(Ntcenterttoptbottomtlefttright(scenterstopRåRæRç( R}RRR~RÖRR&RÑRÕRŒRï(Rátargt_argRÍRRÙtseek((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt _get_gradient_position_and_angle¤ s2         c Cs~xw|D]o}t|tttfƒr1|g}n$t|tttfƒr|}nqxd D]}||kr\|Sq\WqWdS( Ntcircletellipses closest-sidesclosest-corners farthest-sidesfarthest-cornertcontaintcover(RìRís closest-sidesclosest-corners farthest-sidesfarthest-cornerRîRï(R}RRR~RÖRR&RÑ(RáRèRéRê((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_get_gradient_shape_and_size s      cCsŒg}xy|D]q}t|tƒr2|j|ƒq t|tttfƒr x1|D]&}t|tƒrQ|j|ƒPqQqQWq q W|p‹dS(N(R}RŒRòRÖRR&RÑ(RáRÔRèRÙ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_get_gradient_color_stopsÕ s   c sˆt|ƒdkrGt|dtttfƒrGt|dƒjƒ}nt|ƒ‰t|ƒ}t|ƒ‰t t ˆŒ‰ˆdk r’t ˆƒnd|dk r§|ndg}|j d„ˆDƒƒddjd„|pßgDƒƒd‰tˆƒ}d„}||_‡fd †}||_d „}||_‡fd †}||_‡‡fd †}||_‡‡fd †}||_|S(Niicss+|]!\}}d|t|ƒfVqdS(s%s %sN(RŠ(R²RR((s1/Users/kronuz/Development/pyScss/scss/__init__.pys ï ssradial-gradient(s, css'|]}|dk rt|ƒVqdS(N(RÑRŠ(R²RÙ((s1/Users/kronuz/Development/pyScss/scss/__init__.pys ñ sRìcSs tdƒS(NRÂ(R(((s1/Users/kronuz/Development/pyScss/scss/__init__.pytto__css2ô scstdˆƒS(Ns-moz-(R((tto__s(s1/Users/kronuz/Development/pyScss/scss/__init__.pytto__mozø scSstjdƒtdƒS(Ns%PIE does not support radial-gradient.s!-pie-radial-gradient(unsupported)(RQR¯R(((s1/Users/kronuz/Development/pyScss/scss/__init__.pytto__pieü s cstdˆƒS(Ns-webkit-(R((Ró(s1/Users/kronuz/Development/pyScss/scss/__init__.pyt to__webkit scs–dˆdk rtˆƒnddˆdk r9tˆƒndttˆƒg}|jd„ˆDƒƒddjd„|p}gDƒƒd}t|ƒS( NRÞRãR£css+|]!\}}dt|ƒ|fVqdS(scolor-stop(%s, %s)N(RŠ(R²RR((s1/Users/kronuz/Development/pyScss/scss/__init__.pys ss-webkit-gradient(s, css'|]}|dk rt|ƒVqdS(N(RÑRŠ(R²RÙ((s1/Users/kronuz/Development/pyScss/scss/__init__.pys  sRì(RÑt _grad_pointRßRïR÷RR(RáRÍ(RÔtposition_and_angle(s1/Users/kronuz/Development/pyScss/scss/__init__.pytto__owg s'cstˆˆpdƒS(NRã(t_radial_svg_gradient((RÔRø(s1/Users/kronuz/Development/pyScss/scss/__init__.pytto__svg s(RÒR}RÖRR&RëRëRðRñRÛRÕRÑt _positionR÷RRRòRôRõRöRùRû( Rátshape_and_sizeRÍRòRôRõRöRùRû((RóRøRÔs1/Users/kronuz/Development/pyScss/scss/__init__.pyt_radial_gradientâ s0.   '         c st|ƒdkrGt|dtttfƒrGt|dƒjƒ}nt|ƒ‰t|ƒ‰tt ˆŒ‰ˆdk r†t ˆƒndg}|j d„ˆDƒƒddj d„|p¾gDƒƒd‰tˆƒ}d„}||_‡fd †}||_‡fd †}||_‡fd †}||_‡fd †}||_‡fd †}||_‡‡fd†}||_‡‡fd†} | |_|S(Niicss+|]!\}}d|t|ƒfVqdS(s%s %sN(RŠ(R²RR((s1/Users/kronuz/Development/pyScss/scss/__init__.pys $ sslinear-gradient(s, css'|]}|dk rt|ƒVqdS(N(RÑRŠ(R²RÙ((s1/Users/kronuz/Development/pyScss/scss/__init__.pys & sRìcSs tdƒS(NRÂ(R(((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRò) scstdˆƒS(Ns-moz-(R((Ró(s1/Users/kronuz/Development/pyScss/scss/__init__.pyRô- scstdˆƒS(Ns-pie-(R((Ró(s1/Users/kronuz/Development/pyScss/scss/__init__.pyRõ1 scstdˆƒS(Ns-ms-(R((Ró(s1/Users/kronuz/Development/pyScss/scss/__init__.pytto__ms5 scstdˆƒS(Ns-o-(R((Ró(s1/Users/kronuz/Development/pyScss/scss/__init__.pytto__o9 scstdˆƒS(Ns-webkit-(R((Ró(s1/Users/kronuz/Development/pyScss/scss/__init__.pyRö= scsodtˆpdƒtˆpdƒg}|jd„ˆDƒƒddjd„|pVgDƒƒd}t|ƒS(Ntlinears center topcss+|]!\}}dt|ƒ|fVqdS(scolor-stop(%s, %s)N(RŠ(R²RR((s1/Users/kronuz/Development/pyScss/scss/__init__.pys G ss-webkit-gradient(s, css'|]}|dk rt|ƒVqdS(N(RÑRŠ(R²RÙ((s1/Users/kronuz/Development/pyScss/scss/__init__.pys H sRì(Rüt_opposite_positionR÷RR(RáRÍ(RÔRø(s1/Users/kronuz/Development/pyScss/scss/__init__.pyRùA s 'cstˆˆpdƒS(NRä(t_linear_svg_gradient((RÔRø(s1/Users/kronuz/Development/pyScss/scss/__init__.pyRûL s(RÒR}RÖRR&RëRëRñRÛRÕRÑRüR÷RRRòRôRõRÿRRöRùRû( RáRÍRòRôRõRÿRRöRùRû((RóRøRÔs1/Users/kronuz/Development/pyScss/scss/__init__.pyt_linear_gradient s4.  !'          c Gs t|ƒdkrGt|dtttfƒrGt|dƒjƒ}n|}d}t|dttt fƒr†|d}|d }nt t |Œ}t t |ƒjƒŒd\}}tt|ƒ}t||||ƒ}ddtj|ƒ}dt|ƒ}t|ƒS( Niiiÿÿÿÿsdata:s image/svg+xmls;base64,s url("%s")sdata:image/svg+xml(RÒR}RÖRR&RëRÑRRR~RÛRÕRÒR÷R×RßRït __radial_svgtbase64t b64encodeR‚( RáRÔRãtcxtcyR…tsvgturltinline((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRúS s.  "c Gs(t|ƒdkrGt|dtttfƒrGt|dƒjƒ}n|}d}t|dttt fƒr†|d}|d }nt t |Œ}t t |ƒjƒŒd\}}t t t|ƒƒjƒŒd\}}t|||||ƒ}ddtj|ƒ}dt|ƒ} t| ƒS( Niiiÿÿÿÿsdata:s image/svg+xmls;base64,s url("%s")sdata:image/svg+xml(RÒR}RÖRR&RëRÑRRR~RÛRÕRÒR÷R×Rt __linear_svgRRR‚( RáRÔR tx1ty1tx2ty2R R R ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRd s.  "(cCsdjd„|Dƒƒ}|S(NRÂcss+|]!\}}dt|ƒ|fVqdS(s#N(RŠ(R²RR((s1/Users/kronuz/Development/pyScss/scss/__init__.pys v s(R(RÔRÍ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt__color_stops_svgu scCsd|}|S(Ns´%s((tgradientRÍ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt__svg_templatez s cCsYdtt|ƒƒtt|ƒƒtt|ƒƒtt|ƒƒt|ƒf}t|ƒS(NsM%s(RŠRRR(RÔRRRRR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR ƒ scCsJdtt|ƒƒtt|ƒƒtt|ƒƒt|ƒf}t|ƒS(Nsc%s(RŠRRR(RÔRR R…R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRŽ s c@ sjt|ƒj}ts$tdƒ‚n|tkrJtjjƒttdk rÎ tj?d(ƒnXtt!j"tjjƒj#ƒƒƒ}9d)tj*||9f}:d*t@|:ƒ|f}ttƒd+krex1ttd,d-„d.tAƒd/D] };t|;=qQWntBt(|t(|| |&|'ƒƒƒ}tjjƒ|d<||d0<||d1<||d2<|9|d3|>tJ|Ð ssNothing found at '%s's\RR«R›s.pngs.cachec3sMxFˆD]>\}}|dk r7tj|j|ƒƒn tj|ƒVqWdS(N(RÑR|RI(RR(R(s1/Users/kronuz/Development/pyScss/scss/__init__.pytimagesé scss7|]-\}}tjjtjj|ƒƒdVqdS(iN(RòRñRRó(R²RR((s1/Users/kronuz/Development/pyScss/scss/__init__.pys ì sRüt_spacingic3s5|]+}ˆp|jdˆp)|jdfVqdS(iiN(R(R²timage(RR(s1/Users/kronuz/Development/pyScss/scss/__init__.pys  stmodetRGBARRŽiÿsError while saving images %s%s?_=%ss url("%s") %sièRÁcSs t|dS(NR(t sprite_maps(RÙ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRÀm streverseiôs*f*s*k*s*n*s*t*tdeletetdir(iii(iiiN(iiii(KRRÐR|R R!tdatetimetnowRRSRRÌRÍR}R&R×RÖRŒRRÑRÒR½RRÜRR‚RòRñRRQRRRÑt modified_timeRòRtmktimet timetupletgetmtimeRRôR¬RÒR²t ASSETS_URLRturlsafe_b64encodethashlibtmd5tdigestRt ASSETS_ROOTtpickletloadRIR‹tsumtnewRÔRtxrangetcroptpastetsaveRùt exceptionR‚RïR,ttempfiletNamedTemporaryFileRÕtdumptclosetrenameRÌt sprite_images(@R†RÚRR R t dst_colorsRfR´t src_colorst len_colorsR RtrfilesRCRttimesRRtd_objR RÁt asset_filet asset_pathtassetRétsizesRRþt positionstspacingst tot_spacingsRÌRüRt _spacingstwidththeightt new_imaget offsets_xt offsets_ytoffsetRRtiwidthtiheightRRRtpixdatat_yt_xtpixelRR Rt cropped_imageR¡tfiletimeR RÙttmp_dirt cache_tmpRRÍ((RRRs1/Users/kronuz/Development/pyScss/scss/__init__.pyRž sp  &A(G(72 &'6-A "    &   7  3 3" 2522     $$   a#'$ $$   a#'$  $&$     "  c  Cs‡tstdƒ‚n|dkr*d}n;t|ƒj} | d| d| dt| d d ƒf}|dkrzd }n;t|ƒj} | d| d| dt| d d ƒf}|dkrÊd!}n;t|ƒj} | d| d| dt| d d ƒf}|dkrt|ƒn t|d ƒ} |dkrEt|ƒn t|d ƒ} |dkrmt|ƒn t|d ƒ} |dkr•t|ƒn t|d ƒ} | dksÕ| dksÕ| dksÕ| dkrÞt‚n| | | }tjd dd|t|ƒ| fd|ƒ}tj |ƒ}xUt t|ƒƒD]A}|j ||| d||| | d| dfd|ƒq<W| dkrÅ|j d| d|t|ƒd| dfd|ƒn|sd}|rô|t t|ƒƒd7}n|t t|ƒƒ7}|r-|dt t|ƒƒ7}n|r\|dkr\|dt t|ƒƒ7}n||||f}|dt jtjt|ƒƒjƒƒjdƒjddƒ}|d}tjjtj|ƒ}y|j|ƒWn$tk rtjdƒt}nXdtj|f}n|rmt ƒ}|j|ddƒ|j!ƒ}|j"ƒdt j#|ƒ}ndt$|ƒ}t%|ƒS("NsImages manipulation require PILixiªiúiiiiigào@ig@@RR RRŽtfilltgrid_RšRR«R›Rs.pngsError while saving images%s%stformattPNGsdata:image/png;base64,s url("%s")(ixiªiúi(ixiªiúi(iiii(&R|R RÑRŒRÐR½RÿR4R}tDrawR"t rectangleRbRR,R-R.R²R/RR¬RòRñRRÜR0R8RùRQR9RïR+R tgetvalueR=RR‚R(t left_gutterRNt right_gutterROtcolumnst grid_colortbaseline_colortbackground_colorR Rt_heightt_widtht _left_guttert _right_guttert _full_widthRPtdrawRt grid_nameRÁRFRGR toutputtcontents((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt _grid_image„ sr  ,  ,  ,((((0   ? 8A       c Cs<tstdƒ‚nt|ƒj}tt|ƒjƒ}tt|ƒjƒ}|dksf|dkrot‚ntjd|ddkrŽdndd||fd |d|d|d t|dd ƒfƒ}tƒ}|j |d d ƒ|j ƒ}|j ƒd} d| dt j |ƒ} dt| ƒ} t| ƒS(NsImages manipulation require PILiRiitRGBR RRŽigào@R`Ras image/pngsdata:s;base64,s url("%s")(R|R RŒRÐR½RRÿR4R R8RdR=RRR‚R( RŽRNRORRÃR˜RPRrRst mime_typeR R ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt _image_colorÄ s&   /   cCsbt|ƒj}tj|ƒ}|sDtjd|ditd6ƒn|rXt|dƒStdƒS(sm Returns the name of a sprite map The name is derived from the folder than contains the sprites. sNo sprite map found: %sRæRçs*n*N(RRÐR!RSRQRRRïRÑ(RéR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_sprite_map_nameÛ s c Cs·t|ƒj}t|ƒj}tj|ƒ}|o?|j|ƒ}|shtjd|ditd6ƒn-|s•tjd||dditd6ƒn|r­t|ddƒStdƒS( sÉ Returns the relative path (from the images directory) to the original file used when construction the sprite. This is suitable for passing to the image_width and image_height helpers. sNo sprite map found: %sRæRçsNo sprite found: %s in %ss*n*iiN( RRÐR!RSRQRRRïtQuotedStringValueRÑ(Rétspritet sprite_nameR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt _sprite_fileé s 'cCs;t|ƒj}tj|iƒ}ttd„|DƒƒƒS(Ncss$|]}|jdƒs|VqdS(RN(R*(R²R((s1/Users/kronuz/Development/pyScss/scss/__init__.pys ÿ s(RRÐR!RSR&R‚(RéR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_spritesü sc CsŽt|ƒj}t|ƒj}tj|ƒ}|o?|j|ƒ}|shtjd|ditd6ƒn-|s•tjd||dditd6ƒn|r„dtj|d|df}t |pÅd d ƒ}t |pÚd d ƒ}| s|d ks|d kr"|j d kr"||d8}n| sP|d ksA|d kra|j d kra||d8}ndt |ƒ||f} t| ƒStdƒS(s^ Returns the image and background position for use in a single shorthand property sNo sprite map found: %sRæRçsNo sprite found: %s in %ss*n*s %s%s?_=%ss*f*s*t*iRiÿÿÿÿiRiis url(%s) %s %ss0 0( RRÐR!RSRQRRRïRÜR+RR‹R‚( RéRztoffset_xtoffset_yR{RR RR¡R—((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_sprite s& '.. cCsŒt|ƒj}tj|ƒ}|sDtjd|ditd6ƒn|r‚dtj|d|df}dt |ƒ}t|ƒStdƒS( s, Returns a url to the sprite image. sNo sprite map found: %sRæRçs %s%s?_=%ss*f*s*t*surl(%s)N( RRÐR!RSRQRRRïRÜR+R‚RÑ(RéRR ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt _sprite_url s  c Cst|ƒj}t|ƒj}tj|ƒ}|o?|j|ƒ}|shtjd|ditd6ƒn-|s•tjd||dditd6ƒn|rûd}|dk rÌt|t ƒ rÌt |ƒ}n|dkr>|rçd}nt |pód d ƒ}| s*|d ks|d kr>|j d kr>||d8}q>nd}|dk rot|t ƒ rot |ƒ}n|dkrá|rŠd}nt |p–d d ƒ}| sÍ|d ks¾|d krá|j d krá||d8}qánd||f}t|ƒStdƒS(s„ Returns the position for the original image in the sprite. This is suitable for use as a value to background-position. sNo sprite map found: %sRæRçsNo sprite found: %s in %ss*n*RæRçRãiRiÿÿÿÿiRiRäRåis%s %ss0 0N(sleftsrightscenter(stopsbottomscenter( RRÐR!RSRQRRRïRÑR}RRbR‹( RéRzR~RR{RRR¡R—((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_sprite_position+ s< '  .  . cCsbtstdƒ‚n|o't|ƒj}| sI|dksI|dkrRd}n|odt|ƒj}| s†|dks†|dkrd}n|o§tt|ƒjƒ}| sÉ|dksÉ|dkrÒd}nt|ƒ}tjdd d ||fƒ}|jƒ}xÝtdtt ||d ƒƒƒD]¸}t j d|ƒ}t j d|ƒ} t j dd ƒ} tt t j dd ƒ|ƒƒ} |r¢| | | | fn'| t j dd ƒt j dd ƒ| f} | ||d| dfxO|D]%}||dj|ƒ|d7}qóWq`||dj|ƒ|d7}q`Wt|dƒ}t|dƒ}||krŒ|dcdg||7|ƒ}nt|ƒS(sç src_color - a list of or a single color to be replaced by each corresponding dst_color colors spacing - spaces to be added to the image collapse_x, collapse_y - collapsable (layered) image of the given size (x, y) sImages manipulation require PILiRRRšiis\RR«R›sdata:s;base64,s%s%siRR RiRŽiÿsError while saving imageR`Ras url("%s")N(iii(iii(iiii(?R|R RRÐR›RœRÑRRÜRRÖR'R½RR(R)RIRòRñRRþRúR*R‘R}R&R×RŒRRÑRÒRRRR¬RR,R-R.R²R/RR0R+RRJRRR4RÔR2R5R6R7R8RùRQR9RïR RdR=R‚(-RñR’R“RRR RvR RRR”R•R–RER[R—R˜R@RfR´RARBt file_nametfile_extRÁRFRGR RRNRORPRRVRWRXRYRRTRUR RRZRrRs((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt __image_url sÎ( ! A(G(7<A  $' ,   a#-*        !c Cs%t|tt||t||||ƒ S(s÷ Embeds the contents of a file directly inside your stylesheet, eliminating the need for another HTTP request. For small files such images or fonts, this can be a performance benefit at the cost of a larger generated CSS file. (R©RÕRï(RRvRRR RR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt _inline_image‹ sc Cs%t|||||td|||ƒ S(sÚ Generates a path to an asset found relative to the project's images directory. Passing a true value as the second argument will cause the only the path to be returned instead of a `url()` function N(R©RÕRÑ(RñR’R“RRR RR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt _image_url• scCs+tstdƒ‚nt|ƒj}d}yt|d}Wnßtk rd}ttj ƒr y2t tj |ƒƒd\}}|j |ƒ}WqåqåXnEt j jtj |jdƒƒ}t j j|ƒråt |dƒ}n|rtj |ƒ}|j}|d}|t|s(RÔRR:RRÐRíR&(RªR—R¯R°t_p((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR÷ s       cGsvd}t|ƒdkrMt|dtttfƒrMt|dƒjƒ}nd}t|ƒ}|rr||dšsR(R&RÐRÒR:R×RÑR(tlst1tlst2R´RÍ((RÄs1/Users/kronuz/Development/pyScss/scss/__init__.pyt_join–s & cGsct|ƒdkrGt|dtttfƒrGt|dƒjƒ}nt|ƒ}tt|ƒƒS(Nii(RÒR}RÖRR&RëR(R¶((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_length¢s. cGsft|ƒdkrGt|dtttfƒrGt|dƒjƒ}nt|ƒj}t|jƒƒS(Nii(RÒR}RÖRR&RëRÐRÑ(R¶((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_max©s.cGsft|ƒdkrGt|dtttfƒrGt|dƒjƒ}nt|ƒj}t|jƒƒS(Nii(RÒR}RÖRR&RëRÐRu(R¶((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_min°s.cCsX|ot|ƒj}t||ƒ}t|ƒ}x!|D]}||jt|ƒ\}}t||dƒ}|rš|ƒ||‹sR( R}R&RëRRÐRíRþR‚RÔR,RÔ(RiRR¶RÍ((Rs1/Users/kronuz/Development/pyScss/scss/__init__.pyt_append_selector…s" cCsd|r„|dkr„t|tƒrE|jjƒdkrEd}d}qd}ytt|d|ƒƒ}Wqtk r€d}qXny.|dkr™dntt|d|ƒƒ}Wntk rËd}nXy.|dkrádntt|d|ƒƒ}Wntk rd}nXgt||dƒD]}dt |ƒ^q(}t t |ƒƒ}d|d<|S(NRèiiRÐR˜RêR( RÑR}RRÐR­R½RÑRÿR"RbR,RÔ(R#ttoRRÍ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_headers‘s*$   .  .  0 R«cCsJt|ƒj}t|ƒj}ytt|d|ƒƒ}Wntk rSd}nXytt|d|ƒƒ}Wntk r‰|}nX||kr¬||}}t}n d„}|røg|t||dƒƒD]}||t|ƒ^qÕ}n2g|t||dƒƒD]}t|ƒ^q}t t |ƒƒ}d|d<|S(NRÐicSs|S(N((R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRÀºsRêR( RRÐR½RÑRÿR!R"RbRR,RÔ(RÍR#R$R´R%RRÍ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt _enumerate«s(        =2 cCs+|dkr|}d}ntd||ƒS(Ni(RÑR(R#R$((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_rangeÄs  cCs |j|ƒS(N(t convert_to(RÐRˆ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt _convert_toÏscCsKt|tƒr|dSt|tƒr+| St|ƒ}||j|_|S(Niÿÿÿÿ(R}RRRRÐ(tsignRÐR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_invÓs t ParserValuecBseZd„ZRS(cCs ||_dS(N(RÐ(RRÐ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR(âs(RzR{R((((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRástValuecBs.eZed„ƒZed„ƒZed„ƒZed„ƒZd„Zd„Z d„Z d„Z d„Z d „Z d „Zd „Zd „Zd „Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z!RS(ccsFt|ƒ}x3y|jƒ|jƒfVWqtk r>PqXqdS(s4generator to extract operators and operands in pairsN(titertnextt StopIteration(t tokenlisttit((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_operatorOperandsçs   cCs?|j|jkr|jSt|tƒs7t|tƒr;tStS(N(RÀR}RyR(RÙR‡((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt _merge_typeñs cs‡fd†}|S(sk Wrapper function to allow calling any function using Value objects as parameters. cs°d}g}xŽ|D]†}|j|jkrd|dkrI|jdƒ}qdtj||ƒdƒ}n|j|ƒt|tƒrŒ|j}n|j|ƒqWˆ|Œ|_|S(N(RÑRÀRR!R½R}RÐRò(Rátmergedt_argsRè(tfn(s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_funcÿs    ((R$R%((R$s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_wrapùscCsDt|ƒ}t|ƒ}||j|jƒ}|j|kr@|S|S(N(RRÐ(tclsR)tsecondRžR³((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt _do_bitopss  cCsd|jjt|jƒfS(Ns<%s: %s>(RÀRzR²RÐ(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt__repr__scCs|j||tjƒS(N(t_do_cmpsR t__lt__(Rtother((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR,scCs|j||tjƒS(N(R+R t__le__(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR.scCs|j||tjƒS(N(R+R t__eq__(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR/ scCs|j||tjƒS(N(R+R t__ne__(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR0#scCs|j||tjƒS(N(R+R t__gt__(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR1&scCs|j||tjƒS(N(R+R t__ge__(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR2)scCs|j||tjƒS(N(R+R t__cmp__(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR3,scCs|j||tjƒS(N(R+R R3(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt__rcmp__/scCs|j||tjƒS(N(R)R t__and__(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR52scCs|j||tjƒS(N(R)R t__or__(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR65scCs|j||tjƒS(N(R)R t__xor__(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR78scCs|j||tjƒS(N(R)R t__rand__(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR8;scCs|j||tjƒS(N(R)R t__ror__(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR9>scCs|j||tjƒS(N(R)R t__rxor__(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR:AscCs t|jƒS(N(RRÐ(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt __nonzero__DscCs|j||tjƒS(N(t_do_opR R¡(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR¡GscCs|j||tjƒS(N(R<R R¡(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt__radd__JscCs|j||tjƒS(N(R<R t__div__(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR>MscCs|j||tjƒS(N(R<R R>(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt__rdiv__PscCs|j||tjƒS(N(R<R R¤(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR¤SscCs|j||tjƒS(N(R<R R¤(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt__rsub__VscCs|j||tjƒS(N(R<R R³(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR³YscCs|j||tjƒS(N(R<R R³(RR-((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt__rmul__\scCs|jj|ƒS(N(RÐR(RRˆ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR_scCs+t|tƒr|j|_n ||_|S(N(R}RRÐ(RRø((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR½bs ("RzR{t staticmethodR R!R&t classmethodR)R*R,R.R/R0R1R2R3R4R5R6R7R8R9R:R;R¡R=R>R?R¤R@R³RARR½(((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRæs<                          RcBsJeZd„Zd„Zd„Zed„ƒZed„ƒZd„ZRS(cCsß||_|dkr!t|_nºt|tƒrK|jjƒdk|_nt|tƒri|j|_nrt|tƒrt |jƒ|_nNt|t t fƒr´t |ƒ|_n't |ƒjƒdkpÕt |ƒ|_dS(NRžRR¢R RŸR¡(strueRsonsyesRŸR¡( ttokensRÑRÕRÐR}RR­RRRR R½RŠ(RRD((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR(ks   cCs t|jƒS(N(thashRÐ(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt__hash__zscCs|jr dSdS(NRžR¤(RÐ(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt__str__}scCst|tƒr|jn|}t|tƒr6|jn|}|dkrQt}n|dkrft}n|dkr{t}n|dkrt}n|||ƒS(NRžRR¢R RŸR¡R¤R£R¦R¥RCRfR§(strueRsonsyesRŸR¡(sfalseR£soffsnoRCRfs undefined(strueRsonsyesRŸR¡(sfalseR£soffsnoRCRfs undefined(R}RRÐRïRÕ(R'R)R(Rž((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR+€s        cCs‘t|tƒr‡t|tƒr‡t|ƒ}xV|jƒD]H\}}y(||j||j|ƒ|j|t|ttfƒrétd |jƒƒ‚ntd|ƒ‚|dk r+itj|dƒ|6|d6|_ndS( NgRÐsValue is not a Number! (%s)iÿÿÿÿRgY@iRsValue is not a Number! (%r)(RDRÍRÑRÐR}RR RR9RR~RÑR(RRÿRRÌRSR½RÖRR,R&Rë(RRDRˆ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR(±s>       &  cCs"t|jt|jjƒƒfƒS(N(RERÐt frozensetRÍR×(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRFÔscCs)d|jjt|jƒt|jƒfS(Ns <%s: %s, %s>(RÀRzR²RÐRÍ(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR*×scCs t|jƒS(N(R½RÐ(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt__int__ÚscCs t|jƒS(N(R RÐ(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt __float__ÝscCs6|j}|jtj|dƒ}t|ƒ|}|S(Ngð?(R‹RÐt _conv_factorRSRŠ(RR‹R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRGàs cCs¾yt|ƒ}t|ƒ}Wn3tk rQ|t|d|ƒt|d|ƒƒSXtj|jƒ}tj|jƒ}||ksš|dksš|dkr­||j|jƒS|||ƒSdS(NRÐ(RRÿRÑRîRSR‹RÑRÐ(R'R)R(Ržt first_typet second_type((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR+æs  &$c CsŒt|tƒr‡t|tƒr‡t|ƒ}xV|jƒD]H\}}y(||j||j|ƒ|j|R¤RyR³RÀR‹R¡RÌRSRÍRÑR½( R'R)R(RžRÍR³R´Rt first_unitt second_unit((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR<ôsx (  ! !  =  ## cCsºt|ƒ}|j|_xR|jjƒD]A\}}|dkr(|jj|dƒ|j|c|7¥s(R,RÔR‚R×(RR¶((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRP¤scCs t|ƒS(N(RÒ(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR;§scCs&t|jƒd|jkr!dndS(NRii(RÒRÐ(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt__len__ªscCs t|jƒS(N(RŠRÐ(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRG­scCs#ttd„|jjƒDƒƒƒS(Ncss-|]#\}}|dkr||fVqdS(RN((R²R³R´((s1/Users/kronuz/Development/pyScss/scss/__init__.pys ±s(RR‚RÐR×(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt __tuple__°scCst|jƒƒS(N(RRë(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt__iter__³scCst|jƒŒdS(Ni(RÒR×(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRë¶scCst|jƒŒdS(Ni(RÒR×(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRê¹scCstd„|jjƒDƒƒS(Ncss-|]#\}}|dkr||fVqdS(RN((R²R³R´((s1/Users/kronuz/Development/pyScss/scss/__init__.pys ½s(R‚RÐR×(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR×¼scCsOxH|jƒD]:}t|tƒr7tj|ƒr7q nt|ƒr |Sq W|S(N(RëR}R~R(RR(RR´((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR)¿s  N(RzR{RÑR(RFRCR+R<RPR;RQRGRRRSRëRêR×R)(((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR&bs            RŒcBskeZd„Zd„Zd„Zd„Zed„ƒZed„ƒZd„Z d„Z e d„ƒZ RS( c CsM||_d|_i|_|dkr3d|_nt|tƒrw|j}tt|ƒ|ƒ|_idd6|_nÒt|tƒr§|j|_|jj ƒ|_n¢t|t ƒr×|j}|||df|_nrt|t t fƒrŽ|d }d}gt dƒD]D}||dkr%dn%||||krC||n||^q }t |ƒ|_|d}|dkrIid|6|_qIn»t|ttfƒrÇt|ƒ}|||df|_n‚t|tƒrâ|j}nt|ƒ}|jd d ƒjƒtj|ƒr&td|ƒ‚nytt|ƒ|ƒ|_Wny%t|ƒ}|||df|_WqItk rDy©|jdƒ\}}} | jdƒ} |dkr¾t | jdƒƒ}yØgt dƒD]}t||ƒ^qÙ}gt dƒD]<}||dkrdn||dkr4dn||^q} | |ddkr]dn|ddkrsdn|dg7} t | ƒ|_id|6|_Wq&td|ƒ‚q&Xnh|dkr| jdƒ}y gt dƒD]}t||ƒ^qé}|ddgd} | gt ddƒD]<}||dkrIdn||dkr_dn||^q-7} t gtj| d| ddkr™dn| d| ddkr¶dn| dƒD]}|d^qÁ| dgƒ|_id|6|_Wq&td|ƒ‚q&Xntd|ƒ‚WqEtd|ƒ‚qEXqIXnXdS(NiiRŠigào@gð?giÿÿÿÿRƒR’R”RÃRÂsValue is not a Color! (%s)RëRìRêiiÿg€v@igé !çýÿï?(iiii(iiii(gào@gào@gào@gð?(srgbsrgbashslshsla(srgbsrgba(shslshsla(RDRÐttypesRÑR}Rthex2rgbaRÒRŒR9RRÖRR"R½R RRŠR¬R­R(RRÿRRüRRíR›Rœ( RRDthexRRR…RRˆRRÕR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR(És‚         W        )O= )VxcCs(tt|jƒt|jjƒƒfƒS(N(RERRÐRHRTR×(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRFscCs)d|jjt|jƒt|jƒfS(Ns <%s: %s, %s>(RÀRzR²RÐRT(R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR*sc Cs|j}|j}|dks:|dkrŸ|ddkrŸtj|dd|dd|ddƒ\}}}dt|d ƒt|d ƒt|d ƒfS|dkrtj|dd|dd|ddƒ\}}}d t|d ƒt|d ƒt|d ƒt|dƒfSt|dƒt|dƒt|dƒ}}}|jd ƒ\} } }|jd ƒ\} } }|jd ƒ\} } }|ddkrSt|ƒdksÝt|ƒdksÝt|ƒdkr$d t|dd dƒt|dd dƒt|dd dƒfSdt|dƒt|dƒt|dƒfSt|ƒdks‰t|ƒdks‰t|ƒdkrÝdt|dd dƒt|dd dƒt|dd dƒt|dƒfSdt|dƒt|dƒt|dƒt|dƒfS(NR’R”iiigào@ishsl(%s, %s%%, %s%%)g€v@gY@shsla(%s, %s%%, %s%%, %s)Rtsrgb(%s%%, %s%%, %s%%)s #%02x%02x%02xsrgba(%s%%, %s%%, %s%%, %s)srgba(%d, %d, %d, %s)(RˆRÐR›R¦RŠRüRÒR~( RRˆRR˜R™RR…R†R‡R((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRGs&  (6/ 6<26G/6TcCseyt|ƒ}t|ƒ}Wn3tk rQ|t|d|ƒt|d|ƒƒSX||j|jƒS(NRÐ(RŒRÿRÑRÐ(R'R)R(Rž((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR+)s   &c Cs;t|tƒr‡t|tƒr‡t|ƒ}xV|jƒD]H\}}y(||j||j|ƒ|j|‹ss%s:%ds%s:ns @function RÂs$Required function not found: %s (%s)RæRçRÃcss0|]&\}}t|tƒrt|ƒVqdS(N(R}R½RŠ(R²RfR´((s1/Users/kronuz/Development/pyScss/scss/__init__.pys ›scssG|]=\}}t|tƒ r|dkrd|t|ƒfVqdS(Rs%s: %sN(R}R½RŠ(R²RfR´((s1/Users/kronuz/Development/pyScss/scss/__init__.pys œsRëRìcss-|]#\}}|dkrt|ƒVqdS(RN(Rb(R²RfR´((s1/Users/kronuz/Development/pyScss/scss/__init__.pys ¢s(RÈRÉR¬RÐR×R}R½R,RÒRStfnctRõt_css_functions_reRRQRRRÍRÎRïRR(RÌRáRÕt is_functionR[R\t_nameRRfR´R#t_kwargst_fn_at_fn_nR$tnodeRO((s1/Users/kronuz/Development/pyScss/scss/__init__.pytcall…s2.  / 'R cBseZdZRS(sI Another exception object, for when we run out of tokens (RzR{t__doc__(((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR ªsR cBsDeZdd„Zd„Zd„Zd„Zdd„Zd„ZRS(cCsh|j|ƒ||_|dk rdg|_x6|D]+\}}|jj|tj|ƒfƒq2WndS(s Patterns is [(terminal,regex)...] Ignore is [terminal,...]; Input is a string N(R$tignoreRÑtpatternsRòR5RW(RRjRitinputR³R…((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR(±s     cCs(g|_g|_||_d|_dS(Ni(RDt restrictionsRkR—(RRk((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR$Âs   cCsJd}x=|jdD].}d||d|dt|dƒf}qW|S(sL Print the last 10 tokens that have been scanned in RÂiöÿÿÿs%s (@%s) %s = %siii(RDR²(RRrRŸ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR*Ès,c CsŸd}x5tr=d}d}x{|jD]p\}}|rX||krX||jkrXq%n|j|j|jƒ}|r%|}t|jdƒƒ}Pq%q%W|dkréd}|rÇddj |ƒ}nt dt |jƒ|fƒ‚n||jkr |j|7_q |j|} |j| ||j|j| !f}Pq W|dk r›|d|_|j st||j dkr›|j j |ƒ|jj |ƒdSndS( s‘ Should scan another token and add it to the list, self.tokens, and add the restriction to self.restrictions is Bad TokensTrying to find one of s, sSyntaxError[@ char %s: %s]iiÿÿÿÿN(RÑRïRjRiRRkR—RÒR¾Rt SyntaxErrorR²RDRòRl( Rtrestrictttokentbest_patt best_pat_lenRªtregexpR¿tmsgtend_pos((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_scanÑs@ ! "   cCs‡t|jƒ}||kr1||j|ƒ7}n||kr}|rr|j|rr||j|krrtdƒ‚n|j|St‚dS(sà Get the i'th token, and if i is one past the end, then scan for another token; restrict is a list of tokens that are allowed, or 0 for any token. s&Unimplemented: restriction set changedN(RÒRDRuRltNotImplementedErrorR (RRRnt tokens_len((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRos  & cCs\t|jƒ}||krX|j|}|j| |_|j| |_|d|_ndS(Ni(RÒRDRlR—(RRRwRo((s1/Users/kronuz/Development/pyScss/scss/__init__.pytrewinds   N( RzR{RÑR(R$R*RuRoRx(((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR °s    6 t CachedScannercBs_eZdZiZdgZed„ƒZdd„Zd„Z d„Z dd„Z d„Z RS( sF Same as Scanner, but keeps cached tokens for any given input tENDcCs i|_dS(N(t_cache_(R'((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR4&scCscy|j||_WnHtk r^d|_i|_||_tt|ƒj|||ƒnXdS(N( R{t_tokensRõRÑt_CachedScanner__tokenst_CachedScanner__inputtsuperRyR((RRjRiRk((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR(*s    cCs]y|j||_WnBtk rXd|_i|_||_tt|ƒj|ƒnXdS(N( R{R|RõRÑR}R~RRyR$(RRk((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR$3s    cCsl|jdkr"tt|ƒjƒSd}x=|jdD].}d||d|dt|dƒf}q6W|S(NRÂiöÿÿÿs%s (@%s) %s = %siii(R|RÑRRyR*R²(RRrRŸ((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR*<s ,cCsš|jdkrktt|ƒj||ƒ}||j|<|d|jkrg|j|j|j<|_n|S|jj |ƒ}|dkr’t ‚n|SdS(Ni( R|RÑRRyRoR}t_goals_R{R~RSR (RRRnRo((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRoDs   cCs,|jdkr(tt|ƒj|ƒndS(N(R|RÑRRyRx(RR((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRxQsN( RzR{RhR{R€RCR4RÑR(R$R*RoRx(((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRys   tParsercBs8eZd„Zd„Zd„Zd„Zdd„ZRS(cCs||_d|_dS(Ni(t_scannert_pos(Rtscanner((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR(Ws cCs|jj|ƒd|_dS(Ni(R‚R$Rƒ(RRk((s1/Users/kronuz/Development/pyScss/scss/__init__.pyR$[scCs |jj|j|ƒ}|dS(sŽ Returns the token type for lookahead; if there are any args then the list of args is the set of token types to allow i(R‚RoRƒ(RRTttok((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_peek_scCso|jj|jt|gƒƒ}|d|krXtdt|dƒd|fƒ‚n|jd7_|dS(sG Returns the matched text, and moves to the next token isSyntaxError[@ char %s: %s]isTrying to find ii(R‚RoRƒRÔRmR²(RRˆR…((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRugs !'icCs2|jt||jƒ8_|jj|jƒdS(N(RƒRuR‚Rx(RRf((s1/Users/kronuz/Development/pyScss/scss/__init__.pyt_rewindqs(RzR{R(R$R†RuR‡(((s1/Users/kronuz/Development/pyScss/scss/__init__.pyRVs     R6cBs‘eZd>Zd?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUd-d.d/jeƒd0fdVdWdXdYdZd[gZd>d=„ZRS(\s":"R®s[ ]+tCOMMARêtLPARs\(|\[tRPARs\)|\]RzR)tMULs[*]tDIVRtADDs[+]tSUBs-\stSIGNs-(?![a-zA-Z_])tANDs(?=tLTt=(sLTRš(sGTR(sSTRs'[^']*'(sQSTRs"[^"]*"(sNUMs(?:\d+(?:\.\d*)?|\.\d+)(sBOOLs!(?|j|jƒ|jkr\|j|ƒ}||t|ƒ       &  BT6']63B`-?3<WcCs·d}t|tƒs|}n|dkr¯||tkr”i}xQ||tkr||krd||<|t|}||kr‡Pn|}qCWnt|tƒs¯|}q¯n|dkr‘|tkrÔt|}q‘y/ttƒƒ}|j|ƒ|j|ƒ}Wnct k r%t j ri‚qinDt k rh}t jd|||t|tƒt j ri‚qinXd|kr‘d|kr‘|t|%sp :                    $$       222     1      kÿÿÿÿÿ                                           C        J        7 :     æ@    %7 # $  $€   " !                               ...........1     „F²f¤F!   $o7#-ÜpyScss-1.1.5/scss/__main__.py0000644000076500000240000000003111712034302016505 0ustar kronuzstaff00000000000000import tool tool.main() pyScss-1.1.5/scss/_speedups.so0000755000076500000240000017407412034740572017006 0ustar kronuzstaff00000000000000Êþº¾cL €x< Îúíþ¸…Œ__TEXT00__text__TEXT .! €__symbol_stub__TEXTF+ÀF+€__stub_helper__TEXT,L,€__cstring__TEXTT-bT-__unwind_info__TEXT¶/H¶/Œ__DATA000__nl_symbol_ptr__DATA0$0 __la_symbol_ptr__DATA$0€$0)__data__DATA¤0ø¤0__common__DATAœ2__bss__DATA°2(8__LINKEDIT`0@L#"€0@88@Äü@¬¨CtF6 V, Pññ(üTIÓ®áßö5€ dZ[å|¤$  * 4/usr/lib/libpcre.0.dylib 4©/usr/lib/libSystem.B.dylib&ÄED)F+FlU‰å‹Eÿ]ÃU‰åSWVƒìè^‹E‹@…Àt@‰$èƒ8~3‹H‹P‹x ‹X‹@‰D$‰\$‰|$ ‰T$‰L$†$#‰$è?!닆Ü%‹‰$èÇ 1ÀƒÄ^_[]ÃU‰åSWVƒìè_‹·q%‰·&‡&‰$èô …Àˆç‰·a'ŸÅ&‰$èØ …ÀˆËèô ÇD$Ç$èa‡‰'‰D$‡·"‰$ÇD$õÇD$ ÇD$è“ ‰Æÿ‡&‡&‰D$‡Á"‰D$‰4$è- ÿ‡Å&‰\$‡Ï"‰D$‰4$è ‡×"‰$ÇD$ÇD$èɇ (ÿ‹‡ (‰D$‡î"‰D$‰4$èσÄ^_[]ÃU‰åVƒìèX€ã$‰$èô‰Æ…öt‹E ‰D$‰4$ÇD$è‰ðƒÄ^]ÃU‰åVƒì$èX‹uÇFMô‰L$ Mø‰L$€¿!‰D$‹E ‰$è‰Á¸ÿÿÿÿ…Ét‹Eø‹Mô‰L$‰$è' ‰F1ÀƒÄ$^]ÃU‰åVP‹u‹F…Àt‰$èa‹F‹€ ƒÄ^]ÿàU‰åSWVƒì,èZ‹M‹A…À„‹¸Ð…ÿ„ ‚Ö!‰$‰Ë‰UäèÞ‰EðƒÇö1Ò…ÿ‰þHò‰uì‹K;±ÐÎ…ÿI×kú ƒÇ‹Uä‚×!‰Eè‚Ù!‰E䋱؋Eè‰$茉D$Eð‰$èq‹L>ø‹D>ü‹S+‚ä‹ ‰L$‰D$‹Eä‰$èQ‰D$]ð‰$è<‹D>ü‹ >‰L$‰$è;‰Æ‰4$è‰D$‰$è…öt ÿu ‹F‰4$ÿPƒÇ ‹]‹K‹Eì@‰Eì;ÐŒUÿÿÿ‹EðƒÄ,^_[]Âê!‰$èÙ‰EðëåU‰åSWVƒìLèXÇEèÇEä‹MÇAMä‰L$Mè‰L$Mì‰L$ Mð‰L$€ ‰D$‹E ‰$è(‰Á¸ÿÿÿÿ…É„¥èÇEÌ…ÀÇEÐÇEØ…z‹Eð‹H‹QT‰Ñá‰MÈ”Á÷ÂuÇEЄÉÇEØ…3ƒ}Èt ‰$èë‰$èȉlj}ÜÇEØÿªªª ¸w kÇ ‰$è°…ÿ‰EÐéë‰EÐ1À‰Eà‹Eðƒ}Èt‹Mà‰L$‰$èºë‹Mà‰L$‰$èa‰Æ‹F‹PT‰Ð%”Á÷Âu„É…‰…Àt$‰4$ÇD$ès‰Ç‰4$ÇD$èaë"‰4$ÇD$è‰Ç‰4$ÇD$èõ‹OöAWt3‹HöAWt*‰<$‹uØkþ ‰EÔèü‹]Љ;‹EÔ‰$èë‰D;F‰uØ‹}Ü‹Eà@‰Eà9Ç…ÿÿÿ‹E؉D$‹EЉ$è“‹Eì‹H‹QT‰Ñá‰Mà”Á÷Âu „ɾ…Žƒ}àt ‰$è©ë‰$èW‰Ç1öÿªªª ÇEÌwkÇ ‰$èE‰EÌ…ÿ~Q‰}܉÷‹Eìƒ}àt‰|$‰$èZë ‰|$‰$è‹HöAWt‰$kÞ è‹M̉ÇDFG9}Üu´‹Eè‹Mä‰L$‰D$‰t$ ‹ủt$‹E؉D$‹}Љ<$è§‹M‰A‰ø…Àt‰$è¨1À…öt ‰4$èš1ÀƒÄL^_[]ÃU‰åWVƒì è^ÇEôÇEð‹}ƒt@‹E Mð‰L$ Mô‰L$Žw‰L$‰$è$…Àt‹G‹Mô‹Uð‰T$‰L$‰$èõ‹†1ÿƒÄ ^_]ÃU‰åSWVƒì<è^‹]ƒ{„©‹E Mì‰L$ Mð‰L$Žø‰L$‰$è¹…À„~‰uÜ‹Eì‹H‹QT‰Ñá‰Mä”Á÷ÂuÇEè„É¿…”ƒ}ät ‰$èÓë‰$è‰Æ1ÿþªªª ¸w kÆ ‰$èq…ö‰EèëT‰uà‰Eè‰û‹Eìƒ}ät‰\$‰$èë ‰\$‰$è+‹HöAWt‰$k÷ èA‹Mè‰1ÇD1GC9]àu´‹]‹C‹Mð‰|$ ‹uè‰t$‰L$‰$èó‰Ç…öt‰4$èàGƒøwC‹MÜ‹„ÈÈÿà‹´‹‹K‰L$‰$è¡1Àë`‹¬ëã‹T!‰$è1ÀëF‹s‹‹W‰Ð+†ä‹1‹O‰L$‰T$‰t$ Á‰L$‰D$‹EÜ€ü‰$è§ë‹†¼ÿƒÄ<^_[]Ãg_DDU‰åWVƒìè^‹}ƒt2‹E Mô‰L$މL$‰$èß…Àt‹G‹Mô‰L$‰$è“‹†×ÿƒÄ^_]ÃU‰åSWVƒì,èX‰EÜ訅À…x‹E ‹@‹HT‰È%‰Eè”À÷Áu<uÇD$Ç$è{é=ƒ}èt ‹E ‰$èµë ‹E ‰$è`‰Æ1ÿþªªª ¸w kÆ ‰$èP‰Eä…öŽÝ‰uà‰þƒ}èt‰t$‹E ‰$èaë‰t$‹E ‰$è‰Ã‹C‹PT‰Ð%”Á÷Âu„É…†‰uð…Àt$‰$ÇD$è‰Æ‰$ÇD$èë"‰$ÇD$諉Ɖ$ÇD$虋NöAWt-‹HöAWt$‰4$k÷ ‰Eì裋]ä‰3‹Eì‰$è’‰D3G‹uðF9uà…(ÿÿÿ‰|$‹uä‰4$èE…öt‰4$èG‹EÜ‹€~ÿƒÄ,^_[]ÃU‰åVP‹u‹F…Àt‰$è&‹F‹€ ƒÄ^]ÿàU‰åSWVƒì,èX‹u1Ƀ}¿Eþ;u rÇEä‰ð1Ûé ÇEì€J‰Eà‰ð‰ò1Û‰MèÇEä‰UðŠ €ù¯„Ét,€ù „§€ù …°‰Á)ñ…É~V‹UäÚʉUä…ÿuY1ÿëDƒ}t>ƒ}èu8ë<;uFŠ<:õ„Àt$ˆÁ€Á÷€ùrë< tç‹E‰D$‹Eà‰D$‰4$èÉuè‹UðrÇEì‰ðëN…ÛtÆ G»9ÆsÞ‰ù)ñÈŠˆFG»9øuñ‰ÇëÅ€ù u‹UðJƒ}ìEÁEñë ‹UðBÇEìB;U …ÿÿÿ‰Á)ñ…É‹Eäë)‹UäÚÊ…ÿt…ÛtÆ G9Æs‰ù)ñÈŠˆFG9øuö‰ÐƒÄ,^_[]ÃU‰åVƒìè^¾µ…pdžµ†¹‰$ÇD$辆%‰†A‰†U‰†A‰†U‰†A‰†U‰†A ‰†U ‰†A‰†U‰†A‰†U†;‰†A¤‰†U¸‰†A¤‰†U¸‰†A¤‰†U¸‰†A¤ ‰†U¸ ‰†A¤‰†U¸‰†A¤‰†U¸†J‰†Y‰†Y‰†Y‰†Y ‰†Y‰†Y†o‰†]‰†] ‰†]†}‰†¥†ù‰†¥‰†¥†‰†­†Ú‰†­†è‰†¥†›‰†i†ö‰†á†q‰†¹‰†¹‰†¹ƒÄ^]ÃU‰å]ÃU‰åSWVƒì Ç$èè‰Æ…ö„׋} ‹]‰4$ÇD$è.1À…ÿx‰<$躉†È‰|$‰\$‰$è"‰¾Ô1À…ÿx‰<$苾ԉ†Ì‹ŽÈ‰|$‰L$‰$è싆̉†ÐdžØÇ†ÜƆàdžädž艆쉆ð‰†ô‰†øÇ†üdž‰ðƒÄ ^_[]ÃU‰åVP‹u‹†Ì‰$è_‹†È‰$èQƒÄ^]éGU‰åVƒì‹u‹†Ì‰$è/‹ŽÔ…Éy1Àë‰ $è¡‹ŽÔ‰†Ì‹–ȉL$‰T$‰$èý‹†Ì‰†ÐdžØÇ†ÜƆàdžädž艆쉆ð‰†ô‰†øÇ†üdžƒÄ^]ÃU‰åSWVƒìèY‹}‹ŸÌŸÔ·ÇFÇÇF ÇFÇFÇF‹‡Ð‰Mì‘L‰Uè‰{‰Mðëp‰Ÿð1É‹‡ä‰ÂÁâƒø¸Oо‡àÁàÈЃ¿Ü•Á¶ÉÁáÁ‹Eì‹„ˆ4…Àt‰<$ÿЋ‡Ð@9ØGɇЃ¿…Ê9Øs¾…Éu@‰‡Ðë샿Ü~4ƒ>ˆÇ‡ÿÿÿÿ‹Eè‰D$ ‰<$ÇD$ÿÿÿÿÇD$èUëe€¿àtƒ>xWLJþÿÿÿ‹EðëŃ¿ä~?ƒ>x)LJýÿÿÿ‹Eð‰D$ ‰<$ÇD$ÿÿÿÿÇD$èÿ¹}9Ÿð‚âþÿÿ9Ÿð‚Îþÿÿ‰<$èŸýÿÿ‰ðƒÄ^_[]ÃU‰å‹E‹ˆÐŠ ˆˆà]ÃU‰å‹EÆ€à]ÃU‰å‹Eÿ€Üǀ싈ÐA‰ˆô]ÃU‰å‹EÿˆÜ]ÃU‰åVƒì‹u‹†Ð;†Ìv€xÿ#u džèëF‰†ü‹Žì…Ét$‰D$‰ $ÇD$è«øÿÿ…Àt ‹†ì‰†ð‰4$èŽdžìÿ†äƒÄ^]ÃU‰å‹Eÿ€ä]ÃU‰åWVƒìÇEôÿÿÿÿ‹uÿŽäƒ¾è…‹†Ð‰†‹†ð‹ŽüUô‰T$‰L$‰$èøÿÿ‹Môƒùÿu‹ŽØë‰ŽØ‹–ð‰– ‰†‹–üB‰–‹†‰Ç)׉¾‰Ždž@‰†ø‰†ô‰†ðdžìdžèƒÄ^_]ÃU‰å‹Eÿˆä]ÃU‰åVƒìÇEøÿÿÿÿ‹u‹†Ð‰†ð‹Žø9Áw|Uø‰T$‰D$‰ $èT÷ÿÿ…ÀtL‹Møƒùÿu‹ŽØë‰ŽØ‹–ø‰– ‰†dždž‰Ždž‹†Ð@‰†ø‰†ô‰†ðdžìƒÄ^]ÃU‰åVƒì‹u‹†ì…Àt*‹ŽÐ‰L$‰$ÇD$è­öÿÿ…Àt ‹†ì‰†ðdž싆Ð@‰†ôƒÄ^]ÃU‰åVƒì‹u‹†ì…Àt0‹ŽÐ‰L$‰$ÇD$èRöÿÿ‹Žì…Àt‰Žðë(…Éu1‹ŽÐ‹†ô‰L$‰$ÇD$èöÿÿ…Àt ‹†Ð@‰†ìƒÄ^]ÃU‰åVƒìÇEøÿÿÿÿ‹u‹†ð‹Žø9ÁwoUø‰T$‰D$‰ $èÑõÿÿ…ÀtL‹Møƒùÿu‹ŽØë‰ŽØ‹–ø‰– ‰†dždž‰Ždž‹†ð‰†øƒÄ^]ÃU‰åSWVƒì 1À‹]…Ût0‹} 1À‰ùAx"‰ $è^ ‰Æ1À…öt‰|$‰\$‰4$èÄ ‰ðÆ8ƒÄ ^_[]ÃU‰åVƒì‹u‰4$è¶ ‰D$‰4$è˜ÿÿÿƒÄ^]ÃU‰åSWVƒì<è^‹M ‹U< ‰}ð¸9×v/Š€û&€û t€û t€û t€ûƒÀë €û'uñƒÀë@BIuÑ=(¹(Fȉò‹‚J:Áù(r Ç‚J:1ÀÆ„J'´K„J‰EÔºJ:‚°‰Eì‚­‰E肪‰E䂳‰Eà‚§‰E܉UØ‹]ëˆFC;]ðƒ¬¾ƒø&< tS< tC< uWF9øƒ‹Eäë<'uCF9øs}‹E܉D$ ‰4$ÇD$ÿÿÿÿÇD$èS ƒÆë£F9øsR‹EèëÓF9øsF‹EìëÇ<2N9ùs6‰D$‹Eà‰D$ ‰4$ÇD$ÿÿÿÿÇD$è ƒÆéUÿÿÿN9ù‚GÿÿÿÆ'ÆFƒÆ‹MÔ)΋EذJ:‰ÈƒÄ<^_[]ÃU‰åVƒì‹u‰4$èå ‰D$‰4$è5þÿÿƒÄ^]ÃU‰åSWVƒìèX‰Eì»1ö‹ˆm‰Mð‹¸eëƒÆ CSÿ9ú}#‹Eð‹0‹M‰L$‰$èƒ …ÀuÜ‹Eððé§1Àƒ} ‹}섘‹i9Ê|+ƒÁ2‰i1Àùªªª wkÁ ‰D$‹Eð‰$賉‡m‹E‰$è, ‰D$‹E‰$è ýÿÿ‹m‰1‹E ‰$è ‰D$‹E ‰$èèüÿÿ‹m‰D1‹‡mÇD0‰Ÿe·m‰ðƒÄ^_[]ÃU‰åSWVƒì ‹uƒ¾Ð~61ÿ»‹†Ø‹‰$è ‹†Ü‹Dø‰$è÷ƒÃ G;¾Ð|Ñ‹}džЅÿt-‹] ‹†ä…Àt‰$èʼn|$‰$è=üÿÿ‰†ä‰¾àdžèƒÄ ^_[]ÃU‰åWVƒì‹u‹†Ì…Àt‰$è~‹†Ø…ÀtBƒ¾Ð~#1ÿ‹†Ü‹Dø‰$èWG;¾Ð|勆؉$è@‹†Ü‰$è2‹†ä…Àt‰$è ƒÄ^_]éU‰åSWVƒìÇ$ìè‹]‹u ‹}‰$‰EðÇD$ìèP‹Eð…À„²…ö~ƒÇ‹Gü‹‰L$‰$è„ýÿÿƒÇ Nué‹}…ÿthÿÿÿÿ‹uðw½‰$è ‰†Ìëdž̅ÿ~EƒÃ‹Cü‹ ‰L$‰$è3ýÿÿ…Àt‹ŽÈQ‰–È‹–̉ŠƒÃ OuÍë ‹uðdž̋E‰D$‹E‰D$‰4$èóýÿÿ‰ðƒÄ^_[]ÃU‰åèX‹€Y ]ÃU‰å‹M‹U ]éU‰åWVƒìèX‰Ö‰Ï¸4 u*…öt&Ç€4 ~ƒÇ‹Gü‹‰L$‰$è€üÿÿƒÇ NuéƒÄ^_]ÃU‰åSWVƒì è^¾ä „Ž‹†à ¾Ø ~L1ÿ1Û‹8‰$èp‹†à ‹D8‰$è^‹†à ‹L8…Ét‰ $‹†X ÿ‹†à ƒÇ C;žØ |¸‰$è+džà Ç†Ø Ç†Ü džä ƒÄ ^_[]ÃU‰åSWVƒìlèX‰E´‹€Ÿ ‰E¬‹‰Eð‹U‹‚Ћu‹}‹M 9È…µƒÇ‰}°ë)ƒÇ A‰ò9Á‰Ö‹–Ì;Šuå‹E؉ò‚è‹uÇEÐ1Éë‰þ‹MÀA‹E´;ˆ# <kù ‰}¼‰MÀ‹€+ ‰E¸8‰Ẻ÷…ÿte‹‚È9ø‰ÁLωMÄ1Û‹u°ëƒÆ C‹EÈ;]Ä}ª9û}%‹Fü‹‰L$‰$‰×èÛúÿÿ‰ú‹M‰Ï9EÌt‹‚ȉEÈ9Ã}Ä‹ŠÌ‰ø‹}Ì;<™‰Çu²‹M¼‹u¸‹D‹ºè‰}È‹šà‹ºä…Àu2‰ðt‹DMè‰L$ Mì‰L$‰$ÇD$ÇD$èú‰M܉L$‹MȉL$‰\$ ‰û‰\$‰$ÇD$ÇD$ÇD$èÆ…À‹U‹u‰÷ˆËþÿÿ‰þ‹}̉}ЋEÜÉ]Ô‹Mà)Á‰ø‰MØë‹EÐ…Àt‰Ã‹‚È1É‹}°éhþÿÿ‹‚è…öt7‰t$‰D$‹E´€Î‰D$ ‰$ÇD$ÿÿÿÿÇD$èV¸þÿÿÿéi‰D$‹E´€ ‰D$ ‰$ÇD$ÿÿÿÿÇD$è#¸ÿÿÿÿé6‰}Ì‹uÔ‹M؉ð+‚äȉ‚è‰Ð‹Ð‹€Ø…Òtzÿkÿ 98u9t8u 9L8„#‹u‹ŽÔ9Ê|qƒÁ2‰ŽÔ1ÿùªªª ‰òv1ÀëkÉ ‰L$‰$‰Öè6‰ò‹ŠÔ‰‚Øùÿÿÿw!‹‚ÜÁá‰L$‰$‰Öè ‰ò‰Ç‹‚؉ºÜ‰Ñ‹‘ЉÎkÊ Á‹E؉AòEÐò‰ð‹°Ð‹¸Ü‹]…Ûtdûÿÿÿw‰$詉D÷Ç÷ëÇD÷Ç÷…Û~<‹MÌ‹Aü‹ ‰L$‰$è2øÿÿ…Àt‹ ÷Q‰÷‹T÷‰ŠKuÕëÇD÷Ç÷‹Eÿ€Ð¸üÿÿÿ‹U …Ò‹Mˆº¸üÿÿÿ9‘ÐŽ©k Øé›…ÉxÊ;E ~Å‹E‹ˆÜ‹E ƒ<Át³1Òë‹UÈB;U‹E}£kú ‰UÈT8‰UÌÇ1öë(‰Ã‹‹MÌ‹ ‰L$‰$è|÷ÿÿ‹M‹‰Ü‹TÙ;²tºF‹E ;4Á|ЋE´€§‰D$ ‹E‰$ÇD$ÿÿÿÿÇD$èè¸ýÿÿÿ‹M¬‹ ;MðuƒÄl^_[]ÃèÒU‰å‹E …Àx*‹M9Ð~‰ÐkÀ ‹‘Ø‹D+ä‰è]Ãÿ%$0ÿ%(0ÿ%,0ÿ%00ÿ%40ÿ%80ÿ%<0ÿ%@0ÿ%D0ÿ%H0ÿ%L0ÿ%P0ÿ%T0ÿ%X0ÿ%\0ÿ%`0ÿ%d0ÿ%h0ÿ%l0ÿ%p0ÿ%t0ÿ%x0ÿ%|0ÿ%€0ÿ%„0ÿ%ˆ0ÿ%Œ0ÿ%0ÿ%”0ÿ%˜0ÿ%œ0ÿ% 0héÒhéÈh2é¾hGé´h^éªhté h‡é–h™éŒh­é‚hÂéxhÜénhñédh éZh'éPhBéFh]é<hé2h–é(hªéh¾éhÓé hééh0ÿ%0hþéêÿÿÿhéàÿÿÿh$éÖÿÿÿh4éÌÿÿÿhJéÂÿÿÿhcé¸ÿÿÿhpé®ÿÿÿhé¤ÿÿÿhŽéšÿÿÿhéÿÿÿis#s#_speedups_BlockLocatorScanner_speedups.NoMoreTokensNoMoreTokenslocate_blocksLocate Scss blocks.s#scss.ScannerScanner object.OO|z#resetScan the next tokentokenGet the nth tokenrewindRewind scannersetup_patternsInitialize patterns.ii|Oiiss#|z# (@%d) %s = Nonescss._BlockLocatorInternal BlockLocator iterator object.%dMissing closing parenthesis somewhere in blockMissing closing string somewhere in block\'\r\n\t\x%02xUnimplemented: restriction set changedSyntaxError[@ char %d: Trying to find one of the %d restricted tokens!]SyntaxError[@ char %d: Bad Token!] 44G+4 ,,,&,0,:,D,N,X,b,l,v,€,Š,”,ž,¨,²,¼,Æ,Ð,Ú,ð,ú,---"-,-6-@-J-{. 6ëŽ. " õ Ã- W ~ ëÐ-L2Æ ž-µ ¬-æ-Úì-.N..4...Œ(=.!$` Cpp@_PyExc_NotImplementedErrorQq@_PyExc_StopIteration@_PyExc_SyntaxError@_PyType_GenericNew@__Py_NoneStruct@_pcre_free€@___stack_chk_guard€øÿÿÿÿÿÿÿÿ@dyld_stub_binder€àÿÿÿÿÿÿÿÿq$>@_PyArg_ParseTupleq(>@_PyErr_NewExceptionq,>@_PyErr_SetNoneq0>@_PyErr_SetStringq4>@_PyList_GetItemq8>@_PyList_Sizeq<>@_PyMem_Freeq@>@_PyMem_MallocqD>@_PyMem_ReallocqH>@_PyModule_AddObjectqL>@_PyObject_ReprqP>@_PyString_AsStringqT>@_PyString_ConcatAndDelqX>@_PyString_FromFormatq\>@_PyString_FromStringq`>@_PyString_FromStringAndSizeqd>@_PyTuple_GetItemqh>@_PyTuple_Sizeql>@_PyType_Readyqp>@_Py_BuildValueqt>@_Py_InitModule4qx>@__PyObject_Newq|@_pcre_compileq€@_pcre_execq„@___bzeroqˆ@___sprintf_chkqŒ@___stack_chk_failq@_freeq”@_memcpyq˜@_sscanfqœ@_strcmpq @_strlen_scss_hinit_speedupsž_strip£BlockLocator_¨P„repr´Scanner_áfunction_map_initializedÔBlockLocator_iterfunction_mapÙ˜next™¢•Ý*iÎfinalizeënewðdelõrewindúnitializeæternextÿÛ-î0ó0ó2¡3Þ4yMem_Str›attern_Çndupªdup¯î?¸@n½ÂÜ@‰DregexÜpatternsÞ­Dre”del¨new­initialize²finalizeÅtokenÊset£windÏ´FÏGÕHd»ÀËJÜJºKïLVœe e_çŽsz‚bszˆinitialized” å`¤å`¨å`¬å`˜ s @b'È”tæXª'þ“€.½®%|Ó³[{–J$­$‡›†öOµ¡ úÞ lDúÞ ( libpcre.0úÞ ( libSystem.Bd'd3fyÁsP. e$ $ N ." }$" $sNs.• ™$• $ N .µ ¨$µ $@N@.õ ¼$õ $bNb.W Ô$W $'N'.~ ê$~ $HNH.Æ ý$Æ $N.Ú$Ú$tNt.N$$N$æNæ.48$4$XNX.ŒM$Œ$ªNª.6j$6$'N'…&¤0œ&h1®&,2¼&L2Ò& °2ddëdûfzÁsP.]1$]$~N~.Û9$Û$“N“.nR$n$N.si$s{„$N.s™$s$.N..¡«$¡$½N½.^À$^$®N®. ×$ $N."ó$"$N.1 $1$%N%.V.$V$N.dM$d$|N|.ài$à$N.î„$î$ÓNÓ.Áž$Á$N.Ï·$Ï$³N³.‚Ó$‚$[N[.Ýì$Ý${N{.X$X$–N–% ? ddRd\fzÁsP.îŒ$$JNJ.8 ¥$8 $$N$.\ ³$\ $­N­. "º$ "$$N$.-"À$-"$N.4#Ï$4#$›N›.Ï#Þ$Ï#$†N†.U$ë$U$$öNö.K%ø$K%$N.\% $\%$N.k%!$k%$ONO.º%5$º%$µNµ.o&G$o&$¡N¡.+V$+$6N6f { ‘ £ Á& ´2Ð& ´Zdßµ óõ W !~ 4Æ GÚ[No4„Œ¡6¼ Ø"ò1V2dNàiîƒÁœÏ¸‚ÑÝêX k%¤05h1G,2UL2k °2„ ´2“ ´Z¢s´nËÛä^ûs ¡"  ¨24  ¤2J  ¬2h   2} -"Œ 8 š î© Ï#¶ º%È \%Ü K%ñ U$þ 4# + o&, ]4  œ2N • ]  "c \ j  ‚ " ž   2± þà þ× þæ þ÷ þ þ' þ: þJ þW þc þq þ€ þ” þ£ þ¶ þÍ þâ þ÷ þ þ$ þ2 þE þS þb þr þ þ‘ š © » Î Ô Ü ê õ      !"$%&'/0)*+-.2345@#(,1 !"$%&'/0)*+-.234 /usr/local/www/dubalu/libs/scss/src/_speedups.c/usr/local/www/dubalu/libs/scss/src/./_speedups.o_scss_BlockLocator_iter_scss_BlockLocator_iternext_init_speedups_scss_locate_blocks_scss_BlockLocator_init_scss_Scanner_dealloc_scss_Scanner_repr_scss_Scanner_init_scss_Scanner_reset_scss_Scanner_token_scss_Scanner_rewind_scss_Scanner_setup_patterns_scss_BlockLocator_dealloc_scss_BlockLocatorType_scss_ScannerType_scss_methods_scss_Scanner_methods_PyExc_scss_NoMoreTokensblock_locator.c/usr/local/www/dubalu/libs/scss/src/./block_locator.o__strip_BlockLocator_initialize_BlockLocator_finalize_BlockLocator_new/usr/include/secure/_string.h_BlockLocator_del_BlockLocator_rewind_BlockLocator_iternext__BlockLocator_start_string__BlockLocator_end_string__BlockLocator_start_parenthesis__BlockLocator_end_parenthesis__BlockLocator_start_block1__BlockLocator_start_block__BlockLocator_end_block1__BlockLocator_end_block__BlockLocator_end_property__BlockLocator_mark_safe__BlockLocator_mark_thin__BlockLocator_flush_properties_function_map_initialized_scss_function_mapscanner.c/usr/local/www/dubalu/libs/scss/src/./scanner.o_PyMem_Strndup./utils.h_PyMem_Strdup_reprn_repr_Pattern_regex_Scanner_reset_Scanner_del_Scanner_new_Scanner_initialized_Scanner_initialize_Pattern_initialize_Scanner_finalize_Scanner_token_Scanner_rewind_Pattern_patterns_sz_Pattern_patterns_bsz_Pattern_patterns_Pattern_patterns_initialized_reprn.strings_reprn.current_scss_locate_blocks_scss_BlockLocator_init_scss_Scanner_dealloc_scss_Scanner_repr_scss_Scanner_init_scss_Scanner_reset_scss_Scanner_token_scss_Scanner_rewind_scss_Scanner_setup_patterns_scss_BlockLocator_dealloc__BlockLocator_start_string__BlockLocator_end_string__BlockLocator_start_parenthesis__BlockLocator_end_parenthesis__BlockLocator_start_block1__BlockLocator_start_block__BlockLocator_end_block1__BlockLocator_end_block__BlockLocator_end_property__BlockLocator_mark_safe__BlockLocator_mark_thin__BlockLocator_flush_properties_Pattern_initialize_scss_BlockLocatorType_scss_ScannerType_scss_methods_scss_Scanner_methods_PyExc_scss_NoMoreTokens_reprn.strings_reprn.current_BlockLocator_del_BlockLocator_finalize_BlockLocator_initialize_BlockLocator_iternext_BlockLocator_new_BlockLocator_rewind_Pattern_patterns_Pattern_patterns_bsz_Pattern_patterns_initialized_Pattern_patterns_sz_Pattern_regex_PyMem_Strdup_PyMem_Strndup_Scanner_del_Scanner_finalize_Scanner_initialize_Scanner_initialized_Scanner_new_Scanner_reset_Scanner_rewind_Scanner_token__strip_function_map_initialized_init_speedups_repr_reprn_scss_BlockLocator_iter_scss_BlockLocator_iternext_scss_function_map_PyArg_ParseTuple_PyErr_NewException_PyErr_SetNone_PyErr_SetString_PyExc_NotImplementedError_PyExc_StopIteration_PyExc_SyntaxError_PyList_GetItem_PyList_Size_PyMem_Free_PyMem_Malloc_PyMem_Realloc_PyModule_AddObject_PyObject_Repr_PyString_AsString_PyString_ConcatAndDel_PyString_FromFormat_PyString_FromString_PyString_FromStringAndSize_PyTuple_GetItem_PyTuple_Size_PyType_GenericNew_PyType_Ready_Py_BuildValue_Py_InitModule4__PyObject_New__Py_NoneStruct___bzero___sprintf_chk___stack_chk_fail___stack_chk_guard_free_memcpy_pcre_compile_pcre_exec_pcre_free_sscanf_strcmp_strlendyld_stub_binderÏúíþ…(__TEXT@@__text__TEXTdk!d€__stubs__TEXTÐ2ÀÐ2€__stub_helper__TEXT3P3€__cstring__TEXTà4bà4__unwind_info__TEXTB7äB7__eh_frame__TEXT(8Ø(8(__DATA@00@__got__DATA@8@ __nl_symbol_ptr__DATA8@8@'__la_symbol_ptr__DATAH@H@)__data__DATAPAðPA__common__DATA@E$0__bss__DATApE0(H__LINKEDITp00P<("€0P00PÀðPÀ°S ˆV6 k0 Pññ(èiIâ“/jX;bš'­³›æî$  * 8/usr/lib/libpcre.0.dylib 8©/usr/lib/libSystem.B.dylib&ÐUH)V+VpUH‰åHÿH‰ø]ÃUH‰åH‹H…ÿt èûƒ8H‹z.H‹8èF!1À]ÃD‹H L‹@‹HH‹P‹pH=-#0À]é‡!UH‰åSPH‹P.H‰!3H=â1èa!…ÀxH‹2.H‰{1H=<0èC!…ÀyHƒÄ[]ÃèÊ 1ÿ1öè—H=Í"H50/1Ò1ÉA¸õè!H‰ÃHÿ1H5°"Hq1H‰ßè· H5¨"HÓ/HÿÌ/H‰ßèš H=“"1ö1ÒèZ H5š"H‰æ20HÿH‹Ü20H‰ßHƒÄ[]éd UH‰åAVSI‰öH=1è– H‰ÃH…Ût H‰ßL‰ö1ÒèH‰Ø[A^]ÃUH‰åSHƒìH‰ûHÇCH\"HUðHMìH‰÷H‰Æ0ÀèˉÁ¸ÿÿÿÿ…Ét‹uìH‹}ðèy H‰C1ÀHƒÄ[]ÃUH‰åSPH‰ûH‹{H…ÿtèéH‹CH‰ßHƒÄ[]ÿ @UH‰åAWAVAUATSPI‰ýI‹EH…À„ö‹˜Ø…Û„èH=h"è™H‰EЃÃö…ÛA¾DIóI‹MD;±Ø©L}ÐH‹™àH=."è^L‰ÿH‰ÆèGIcÆL$@B‹tãI‹E+°øJ‹ãH‹H=ü!0Àè"L‰ÿH‰ÆèJctãJ‹|ãèH‰ÃH‰ßèëL‰ÿH‰ÆèìH…ÛtHÿ u H‹CH‰ßÿP0I‹MAÿÆD;±ØŒ_ÿÿÿH‹EÐHƒÄ[A\A]A^A_]ÃH=”!è±H‰EÐëßUH‰åAWAVAUATSHƒìXH‰}ˆHÇEÀÇE¼HÇGHÀ HUÐHMÈLEÀLM¼H‰÷H‰Æ0Àè‰Á¸ÿÿÿÿ…É„ºèÀ1ÉH‰M°HÇE …À»A¼…lH‹}ÐH‹GH‹ˆ¨H‰ÈH%H‰E˜”À÷Áu„Àt 1ÛE1äé,Hƒ}˜tè÷ëè¨I‰ÆE1ÿH¸UUUUUUUI9Æ»wJõH<@è‰H‰ÃE1äM…öŽßL‰uH‰]¨A¾H‹}ÐHƒ}˜t L‰þèëL‰þè=H‰ÃH‹CH‹¨H‰ÐH%”Á÷Âu„ÉuzH‰ß1öH…ÀtèPI‰ÇH‰ß¾è@ëèñI‰ÇH‰ß¾èáI‰ÅI‹Gö€«t4I‹Eö€«t'L‰ÿèæMcäOI‰Ç1ÛH¸UUUUUUUI9ǸwJýH<@è H‰E¸1ÀH‰EÈM…ÿŽëL‰}°A¿Hƒ}Àt L‰÷H‰Þè'ë L‰÷H‰ÞèÒH‰ÃH‹CH‹¨H‰ÐH%”Á÷Âu„É…ˆH‰ß1öH…ÀtèáI‰ÆH‰ß¾èÑëè‚I‰ÆH‰ß¾èrI‰ÄI‹Fö€«t>I‹D$ö€«t0L‰÷èvL‹mÈMcíOtmH‹]¸J‰óL‰çèZJ‰DóAÿÅL‰mÈL‹uÐIcßAÿÇH;]°ŒÿÿÿH‹]¸H‰ßH‹uÈèÁH…ÛtH‰ßèÿH‹$$HÿHƒÄ([A\A]A^A_]ÃUH‰åSPH‰ûH‹{H…ÿtèsH‹CH‰ßHƒÄ[]ÿ @UH‰åAWAVAUATSHƒìH‰UÈH‰uÀI‰þ1ÿH…ÒA½MEîÇEÔI9ör L‰ñ1ÛM‰÷éºI¼L‰ñ1ÛM‰÷AŠ<¸„Àt-< „°< …¸‰ÈD)ø…À~R‹UÔÚ‰UÔM…íuQE1íë>Hƒ}Èt7H…ÿu2ëIÿÇA¶Hƒø;w I£ÄríH…ÀtL‰ÿH5BH‹UÈ0ÀètL‰ÿM~ºL‰ùëU…ÛtAÆE IÿÅ»I9ÏsÜL‰èL)øHÁAŠAˆEIÿÇIÿÅ»L9éuéI‰Íë·< uIF…ÒHEÈLEøëIN1ÒIÿÆL;uÀ…ÿÿÿ‰ÈD)ø…À~;‹UÔÚ‰UÔM…ít,…ÛtAÆE IÿÅI9ÏsL‰èL)øHÁAŠAˆEIÿÇIÿÅL9éuî‹EÔHƒÄ[A\A]A^A_]ÃUH‰åAVSƒ=_'…£ÇO'H=X'¾0è^H 3H‰ P(H‰ q(H‰ B(H‰ c(H=%HBLÎL oL±LžL5¿H¬H5.H‰ õ'H‰ (H‰ ç'H‰ (H‰ Ù' H‰ ú' H‰ Ë'(HêH‰ å'(H‰=¶7H‰=×_H‰=¨7 H‰=É_ H‰=š7H‰=»_H‰=Œ7H‰=­_H‰=~7!H‰=Ÿ_!H‰=p7)H gH‰=Š_)H‰ ‹'H‰ „'H‰ }'H‰ v'H‰ o' H‰ h'(H‰i'H‰b'H‰['(H‰5ä)H‰Ý)H‰Ö) L‰5ß)L‰Ø) L‰Á'L‰ B'L‰+&H‰Ô%H‰Í%H‰Æ% [A^]ÃUH‰å]ÃUH‰åAWAVATSA‰öI‰ÿ¿PèJH‰ÃH…Û„ÐH‰ß¾Pè—Mcæ1ÿE…öx L‰çèH‰ÇH‰»ÈL‰þL‰âèˆD‰³à1ÿE…öxL‰çèôH‰ÇD‹³àH‰»ÐIcÖH‹³ÈèRH‹ƒÐH‰ƒØÇƒðǃôƃìHǃäH‰ƒøH‰ƒH‰ƒH‰ƒHǃ HǃH‰Ø[A\A^A_]ÃUH‰åSPH‰ûH‹»ÐèÅH‹»Èè¹H‰ßHƒÄ[]é«UH‰åSPH‰ûH‹»Ðè–Hc»àH…ÿy1Àë è ‹»àH‰ƒÐHc×H‹³ÈH‰ÇèhH‹ƒÐH‰ƒØÇƒðǃôƃìHǃäH‰ƒøH‰ƒH‰ƒH‰ƒHǃ HǃHƒÄ[]ÃUH‰åAWAVAUATSPH‰ûLc«àL«ÐL³(IÇF IÇFIÇFIÇFIÇH‹ƒØL=lL%”ë|L‰«1É‹ƒð‰ÂÁâƒø¸OоƒìÁàÈЃ»è•Á¶ÉÁáÁHcÁH &#H‹ÁH…ÀtH‰ßÿÐH‹ƒØHÿÀL9èIGÅH‰ƒØƒ»(…ÍL9ès¾…ÉuHÿÀH‰ƒØë胻è~,Aƒ>ˆÇƒ(ÿÿÿÿH‰ß1öHÇÂÿÿÿÿL‰ù0Àè¾ëk€»ìt!Aƒ>x\ǃ(þÿÿÿH‰ß1öHÇÂÿÿÿÿL‰áë̓»ð~8Aƒ>x ǃ(ýÿÿÿH‰ß1öHÇÂÿÿÿÿL‰á0Àèc¹}L9«‚ÕþÿÿL9«‚¿þÿÿH‰ßèýÿÿL‰ðHƒÄ[A\A]A^A_]ÃUH‰åH‹‡ØŠˆ‡ì]ÃUH‰åƇì]ÃUH‰åÿ‡èHLJøH‹‡ØHÿÀH‰‡]ÃUH‰åÿè]ÃUH‰åSPH‰ûH‹³ØH;³Ðv€~ÿ#u ǃôë?H‰³H‹»øH…ÿt1Òèaøÿÿ…ÀtH‹ƒøH‰ƒH‰ßè„HǃøÿƒðHƒÄ[]ÃUH‰åÿ‡ð]ÃUH‰åSPH‰ûÇEôÿÿÿÿÿ‹ðƒ»ô…¤H‹ƒØH‰ƒ H‹»H‹³HUôèÛ÷ÿÿ‹Môƒùÿu‹‹ä뉋äH‹“H‰“0‰ƒ8H‹“HÿÂH‰“@H‹ƒ ‰Æ)Ö‰³H‰‹,ǃ(HÿÀH‰ƒH‰ƒH‰ƒHǃøÇƒôHƒÄ[]ÃUH‰åÿð]ÃUH‰åSPH‰ûÇEôÿÿÿÿH‹³ØH‰³H‹»H9÷w{HUôè ÷ÿÿ…ÀtO‹Môƒùÿu‹‹ä뉋äH‹“H‰“0‰ƒ8Hǃ@ǃH‰‹,ǃ(H‹ƒØHÿÀH‰ƒH‰ƒH‰ƒHǃøHƒÄ[]ÃUH‰åSPH‰ûH‹»øH…ÿt H‹³Ø1Òèeöÿÿ…ÀtH‹ƒøH‰ƒHǃøH‹ƒØHÿÀH‰ƒHƒÄ[]ÃUH‰åSPH‰ûH‹»øH…ÿt'H‹³Ø1Òè öÿÿH‹‹ø…Àt H‰‹ëH…Éu*H‹³ØH‹»1Òèßõÿÿ…ÀtH‹ƒØHÿÀH‰ƒøHƒÄ[]ÃUH‰åSPH‰ûÇEôÿÿÿÿH‹³H‹»H9÷wjHUôè—õÿÿ…ÀtO‹Môƒùÿu‹‹ä뉋äH‹“H‰“0‰ƒ8Hǃ@ǃH‰‹,ǃ(H‹ƒH‰ƒHƒÄ[]ÃUH‰åAWAVSPI‰÷I‰þ1ÀM…öt/1ÀL‰ÿHÿÇx èË H‰Ã1ÀH…ÛtH‰ßL‰öL‰úè1 H‰ØBÆ8HƒÄ[A^A_]ÃUH‰åSPH‰ûè" H‰ßH‰ÆHƒÄ[]éÿÿÿUH‰åAWAVAUATSPI‰ÿM,7¸M9ýv:L‰ùŠ€ú&€ú t€ú t€ú t€úHƒÀë€ú'uðHƒÀëHÿÀHÿÁHÿÎuÉH=(¹(HFÈH‹˜E0HÁHù(r HÇE01ÀL5x0BÆ0'J\0IÆL%dE0ë DˆHÿÃIÿÇM9ïƒ÷E¾Aƒø&qï= Ùª Ô o +14Ø.¥±‰•¥öê ÅS9O‘D5!zRx $Ùÿÿÿÿÿÿ A†C $DÙÿÿÿÿÿÿKA†C $l#ÙÿÿÿÿÿÿçA†C Bƒ$”âÙÿÿÿÿÿÿ3A†C CƒŽ$¼íÙÿÿÿÿÿÿTA†C Eƒ$äÚÿÿÿÿÿÿ*A†C Bƒ, Úÿÿÿÿÿÿ&A†C JƒŒŽ,<Ûÿÿÿÿÿÿ(A†C MƒŒŽ$l ÞÿÿÿÿÿÿcA†C Eƒ,”DÞÿÿÿÿÿÿÞA†C MƒŒŽ$ÄàÿÿÿÿÿÿIA†C Bƒ,ì%àÿÿÿÿÿÿÑA†C MƒŒŽ$Æáÿÿÿÿÿÿ*A†C BƒzRx ,°áÿÿÿÿÿÿ›A†C MƒŒŽ$Lãÿÿÿÿÿÿ¼A†C CƒŽ$t¯äÿÿÿÿÿÿA†C ,œäÿÿÿÿÿÿA†C GƒŒŽ$Ì`åÿÿÿÿÿÿ/A†C Bƒ$ôgåÿÿÿÿÿÿ¶A†C Bƒ,õåÿÿÿÿÿÿ¿A†C JƒŒŽ$L„çÿÿÿÿÿÿA†C $tqçÿÿÿÿÿÿ A†C $œVçÿÿÿÿÿÿ(A†C $ÄVçÿÿÿÿÿÿ A†C $ì:çÿÿÿÿÿÿwA†C Bƒ$‰çÿÿÿÿÿÿ A†C $<mçÿÿÿÿÿÿØA†C Bƒ$dèÿÿÿÿÿÿ A†C $Œèÿÿÿÿÿÿ·A†C Bƒ$´èÿÿÿÿÿÿXA†C Bƒ$ÜÀèÿÿÿÿÿÿmA†C Bƒ$éÿÿÿÿÿÿ”A†C BƒzRx $YéÿÿÿÿÿÿQA†C FƒŽ$D‚éÿÿÿÿÿÿA†C Bƒ,lyéÿÿÿÿÿÿÕA†C JƒŒŽ$œëÿÿÿÿÿÿA†C Bƒ,ÄëÿÿÿÿÿÿA†C JƒŒŽ,ôìëÿÿÿÿÿÿµA†C GƒŒŽ$$qìÿÿÿÿÿÿŽA†C CƒŽ,L×ìÿÿÿÿÿÿæA†C MƒŒŽ$|íÿÿÿÿÿÿ A†C $¤qíÿÿÿÿÿÿ A†C $ÌSíÿÿÿÿÿÿBA†C CƒŽ$ômíÿÿÿÿÿÿ³A†C FƒŽ,øíÿÿÿÿÿÿñA†C PƒŒŽ$L¹òÿÿÿÿÿÿ6A†C 3š3¤3®3¸3Â3Ì3Ö3à3ê3ô3þ3444&404:4D4N4X4b4|4†44š4¤4®4¸4Â4Ì4Ö4*5¢85r5¡x5Œ5’5¤5ô«5º5=(É5O5)Së\5Ay6ë6dpÕ!H` ARAp RASASASAp8pp pPp0p8ppppxp RHQ>@_PyExc_NotImplementedErrorQq@_PyExc_StopIteration@_PyExc_SyntaxError@_PyType_GenericNew@__Py_NoneStruct@_pcre_free€@___stack_chk_guard€ðÿÿÿÿÿÿÿÿ@dyld_stub_binder€qH>@_PyArg_ParseTupleqP>@_PyErr_NewExceptionqX>@_PyErr_SetNoneq`>@_PyErr_SetStringqh>@_PyList_GetItemqp>@_PyList_Sizeqx>@_PyMem_Freeq€>@_PyMem_Mallocqˆ>@_PyMem_Reallocq>@_PyModule_AddObjectq˜>@_PyObject_Reprq >@_PyString_AsStringq¨>@_PyString_ConcatAndDelq°>@_PyString_FromFormatq¸>@_PyString_FromStringqÀ>@_PyString_FromStringAndSizeqÈ>@_PyTuple_GetItemqÐ>@_PyTuple_SizeqØ>@_PyType_Readyqà>@_Py_BuildValueqè>@_Py_InitModule4_64qð>@__PyObject_Newqø@_pcre_compileq€@_pcre_execqˆ@___bzeroq@___sprintf_chkq˜@___stack_chk_failq @_freeq¨@_memcpyq°@_sscanfq¸@_strcmpqÀ@_strlen_scss_hinit_speedupsž_strip£BlockLocator_¨P„repr´Scanner_áfunction_map_initializedÔBlockLocator_iterfunction_mapÚä"next™ð"»#¸8iÎfinalizeënewðdelõrewindúnitializeæternextÿÓ;?•?˜AÇAýByMem_Str›attern_Çndupªdup¯‰NÚNn½ÂùNÎRregexÜpatternsàíRre”del¨new­initialize²finalizeÅtokenÊset£windÏôT©V·Wd»ÀY©YõY¨[™eÀŠЊ_é’sz„bsz‹initialized™ЊÁÔŠÁØŠÁàŠÁä" Kç3T*¦¨cðIÑ*›¼ƒ/¶¿ ( w Ø ·Xm”QÕ‡µŽæ B³ñ úÞ lDúÞ ( libpcre.0úÞ ( libSystem.Bd'd3fyÁsP.de$d$ N .p}$p$KNK.»™$»$çNç.¢¨$¢$3N3.Õ¼$Õ$TNT.)Ô$)$*N*.Sê$S$&N&.yý$y$(N(.¡$¡$cNc.$$$ðNð.ô8$ô$INI.=M$=$ÑNÑ.j$$*N*…& PA“& A©& 0B»& ¸CÒ& pE0ddëdûfzÁsP.81$8$›N›.Ó9$Ó$¼N¼.R$$N.•i$•{„$N.˜ ™$˜ $/N/.Ç «$Ç $¶N¶.}!À$}!$¿N¿.<#×$<#$N.Q#ó$Q#$ N .^# $^#$(N(.†#.$†#$ N .’#M$’#$wNw. $i$ $$ N .$„$$$ØNØ.í$ž$í$$ N .ù$·$ù$$·N·.°%Ó$°%$XNX.&ì$&$mNm.u&$u&$”N”% ? ddRd\fzÁsP. 'Œ$ '›„$QNQ.Z'¥$Z'$N.y'³$y'$ÕNÕ.N)º$N)$N.m)À$m)$N.t*Ï$t*$µNµ.)+Þ$)+$ŽNŽ.·+ë$·+$æNæ.,ø$,$ N .©, $©,$ N .³,!$³,$BNB.õ,5$õ,$³N³.¨-G$¨-$ñNñ.™2V$™2$6N6f { ‘ £ Á& €E0Ð& €m0dߢóÕ )!S4yG¡[oô„=¡¼<#ØQ#ò^#†#2’#N $i$ƒí$œù$¸°%Ñ&êu& ³, PA, AB 0BT ¸Ck pE0„ €E0“ €m0¢˜ ´ËÓä}!û• Ç "  XE04  TE0J  `E0h  PE0} m)Œ Z'š  '© )+¶ õ,È ©,Ü ,ñ ·+þ t* ™2 ¨-, 84  @EN »] N)c y'j d‚ pž  PE± þà þ× þæ þ÷ þ þ' þ: þJ þW þc þq þ€ þ” þ£ þ¶ þÍ þâ þ÷ þ þ$ þ2 þE þS þb þu þ„ þ”  ¬ ¾ Ñ × ß í ø      !"$%&'/0)*+-.234#(,15@ !"$%&'/0)*+-.234 /usr/local/www/dubalu/libs/scss/src/_speedups.c/usr/local/www/dubalu/libs/scss/src/./_speedups.o_scss_BlockLocator_iter_scss_BlockLocator_iternext_init_speedups_scss_locate_blocks_scss_BlockLocator_init_scss_Scanner_dealloc_scss_Scanner_repr_scss_Scanner_init_scss_Scanner_reset_scss_Scanner_token_scss_Scanner_rewind_scss_Scanner_setup_patterns_scss_BlockLocator_dealloc_scss_methods_scss_Scanner_methods_scss_ScannerType_scss_BlockLocatorType_PyExc_scss_NoMoreTokensblock_locator.c/usr/local/www/dubalu/libs/scss/src/./block_locator.o__strip_BlockLocator_initialize_BlockLocator_finalize_BlockLocator_new/usr/include/secure/_string.h_BlockLocator_del_BlockLocator_rewind_BlockLocator_iternext__BlockLocator_start_string__BlockLocator_end_string__BlockLocator_start_parenthesis__BlockLocator_end_parenthesis__BlockLocator_start_block1__BlockLocator_start_block__BlockLocator_end_block1__BlockLocator_end_block__BlockLocator_end_property__BlockLocator_mark_safe__BlockLocator_mark_thin__BlockLocator_flush_properties_function_map_initialized_scss_function_mapscanner.c/usr/local/www/dubalu/libs/scss/src/./scanner.o_PyMem_Strndup./utils.h_PyMem_Strdup_reprn_repr_Pattern_regex_Scanner_reset_Scanner_del_Scanner_new_Scanner_initialized_Scanner_initialize_Pattern_initialize_Scanner_finalize_Scanner_token_Scanner_rewind_Pattern_patterns_sz_Pattern_patterns_bsz_Pattern_patterns_Pattern_patterns_initialized_reprn.strings_reprn.current_scss_locate_blocks_scss_BlockLocator_init_scss_Scanner_dealloc_scss_Scanner_repr_scss_Scanner_init_scss_Scanner_reset_scss_Scanner_token_scss_Scanner_rewind_scss_Scanner_setup_patterns_scss_BlockLocator_dealloc__BlockLocator_start_string__BlockLocator_end_string__BlockLocator_start_parenthesis__BlockLocator_end_parenthesis__BlockLocator_start_block1__BlockLocator_start_block__BlockLocator_end_block1__BlockLocator_end_block__BlockLocator_end_property__BlockLocator_mark_safe__BlockLocator_mark_thin__BlockLocator_flush_properties_Pattern_initialize_scss_methods_scss_Scanner_methods_scss_ScannerType_scss_BlockLocatorType_PyExc_scss_NoMoreTokens_reprn.strings_reprn.current_BlockLocator_del_BlockLocator_finalize_BlockLocator_initialize_BlockLocator_iternext_BlockLocator_new_BlockLocator_rewind_Pattern_patterns_Pattern_patterns_bsz_Pattern_patterns_initialized_Pattern_patterns_sz_Pattern_regex_PyMem_Strdup_PyMem_Strndup_Scanner_del_Scanner_finalize_Scanner_initialize_Scanner_initialized_Scanner_new_Scanner_reset_Scanner_rewind_Scanner_token__strip_function_map_initialized_init_speedups_repr_reprn_scss_BlockLocator_iter_scss_BlockLocator_iternext_scss_function_map_PyArg_ParseTuple_PyErr_NewException_PyErr_SetNone_PyErr_SetString_PyExc_NotImplementedError_PyExc_StopIteration_PyExc_SyntaxError_PyList_GetItem_PyList_Size_PyMem_Free_PyMem_Malloc_PyMem_Realloc_PyModule_AddObject_PyObject_Repr_PyString_AsString_PyString_ConcatAndDel_PyString_FromFormat_PyString_FromString_PyString_FromStringAndSize_PyTuple_GetItem_PyTuple_Size_PyType_GenericNew_PyType_Ready_Py_BuildValue_Py_InitModule4_64__PyObject_New__Py_NoneStruct___bzero___sprintf_chk___stack_chk_fail___stack_chk_guard_free_memcpy_pcre_compile_pcre_exec_pcre_free_sscanf_strcmp_strlendyld_stub_binderpyScss-1.1.5/scss/config.py0000644000076500000240000000112312105410230016230 0ustar kronuzstaff00000000000000################################################################################ # Configuration: import os PROJECT_ROOT = os.path.normpath(os.path.dirname(os.path.abspath(__file__))) # Sass @import load_paths: LOAD_PATHS = os.path.join(PROJECT_ROOT, 'sass/frameworks') # Assets path, where new sprite files are created: STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static') # Assets path, where new sprite files are created: ASSETS_ROOT = os.path.join(PROJECT_ROOT, 'static/assets') # Urls for the static and assets: STATIC_URL = '/static/' ASSETS_URL = '/static/assets/' VERBOSITY = 1 DEBUG = 0 pyScss-1.1.5/scss/config.pyc0000644000076500000240000000107712105410573016415 0ustar kronuzstaff00000000000000ó ˜Qc@s‘ddlZejjejjejjeƒƒƒZejjedƒZejjedƒZ ejjedƒZ dZ dZ dZ dZdS( iÿÿÿÿNssass/frameworkststatics static/assetss/static/s/static/assets/ii(tostpathtnormpathtdirnametabspatht__file__t PROJECT_ROOTtjoint LOAD_PATHSt STATIC_ROOTt ASSETS_ROOTt STATIC_URLt ASSETS_URLt VERBOSITYtDEBUG(((s)/usr/local/www/dubalu/libs/scss/config.pyts *pyScss-1.1.5/scss/scss_meta.py0000644000076500000240000000471212107520245016765 0ustar kronuzstaff00000000000000#!/usr/bin/env python #-*- coding: utf-8 -*- """ pyScss, a Scss compiler for Python @author German M. Bravo (Kronuz) @version 1.1.5 @see https://github.com/Kronuz/pyScss @copyright (c) 2012-2013 German M. Bravo (Kronuz) @license MIT License http://www.opensource.org/licenses/mit-license.php pyScss compiles Scss, a superset of CSS that is more powerful, elegant and easier to maintain than plain-vanilla CSS. The library acts as a CSS source code preprocesor which allows you to use variables, nested rules, mixins, andhave inheritance of rules, all with a CSS-compatible syntax which the preprocessor then compiles to standard CSS. Scss, as an extension of CSS, helps keep large stylesheets well-organized. It borrows concepts and functionality from projects such as OOCSS and other similar frameworks like as Sass. It's build on top of the original PHP xCSS codebase structure but it's been completely rewritten, many bugs have been fixed and it has been extensively extended to support almost the full range of Sass' Scss syntax and functionality. Bits of code in pyScss come from various projects: Compass: (c) 2009 Christopher M. Eppstein http://compass-style.org/ Sass: (c) 2006-2009 Hampton Catlin and Nathan Weizenbaum http://sass-lang.com/ xCSS: (c) 2010 Anton Pawlik http://xcss.antpaw.org/docs/ This file defines Meta data, according to PEP314 (http://www.python.org/dev/peps/pep-0314/) which is common to both pyScss and setup.py distutils. We create this here so this information can be compatible with BOTH Python 2.x and Python 3.x so setup.py can use it when building pyScss for both Py3.x and Py2.x """ VERSION_INFO = (1, 1, 5) DATE_INFO = (2013, 2, 15) # YEAR, MONTH, DAY VERSION = '.'.join(str(i) for i in VERSION_INFO) REVISION = '%04d%02d%02d' % DATE_INFO BUILD_INFO = "pyScss v" + VERSION + " (" + REVISION + ")" AUTHOR = "German M. Bravo (Kronuz)" AUTHOR_EMAIL = 'german.mb@gmail.com' URL = 'http://github.com/Kronuz/pyScss' DOWNLOAD_URL = 'http://github.com/Kronuz/pyScss/tarball/v' + VERSION LICENSE = "MIT" PROJECT = "pyScss" if __name__ == "__main__": print('VERSION = ' + VERSION) print('REVISION = ' + REVISION) print('BUILD_INFO = ' + BUILD_INFO) print('AUTHOR = ' + AUTHOR) print('AUTHOR_EMAIL = ' + AUTHOR_EMAIL) print('URL = ' + URL) print('LICENSE = ' + LICENSE) print('PROJECT = ' + PROJECT) pyScss-1.1.5/scss/scss_meta.pyc0000644000076500000240000000545312107522123017130 0ustar kronuzstaff00000000000000ó ¥ Qc@sÎdZdZdZdjd„eDƒƒZdeZd ed ed Zd Zd ZdZ deZ dZ dZ e dkrÊdeGHdeGHdeGHdeGHdeGHde GHde GHde GHndS(sŒ pyScss, a Scss compiler for Python @author German M. Bravo (Kronuz) @version 1.1.5 @see https://github.com/Kronuz/pyScss @copyright (c) 2012-2013 German M. Bravo (Kronuz) @license MIT License http://www.opensource.org/licenses/mit-license.php pyScss compiles Scss, a superset of CSS that is more powerful, elegant and easier to maintain than plain-vanilla CSS. The library acts as a CSS source code preprocesor which allows you to use variables, nested rules, mixins, andhave inheritance of rules, all with a CSS-compatible syntax which the preprocessor then compiles to standard CSS. Scss, as an extension of CSS, helps keep large stylesheets well-organized. It borrows concepts and functionality from projects such as OOCSS and other similar frameworks like as Sass. It's build on top of the original PHP xCSS codebase structure but it's been completely rewritten, many bugs have been fixed and it has been extensively extended to support almost the full range of Sass' Scss syntax and functionality. Bits of code in pyScss come from various projects: Compass: (c) 2009 Christopher M. Eppstein http://compass-style.org/ Sass: (c) 2006-2009 Hampton Catlin and Nathan Weizenbaum http://sass-lang.com/ xCSS: (c) 2010 Anton Pawlik http://xcss.antpaw.org/docs/ This file defines Meta data, according to PEP314 (http://www.python.org/dev/peps/pep-0314/) which is common to both pyScss and setup.py distutils. We create this here so this information can be compatible with BOTH Python 2.x and Python 3.x so setup.py can use it when building pyScss for both Py3.x and Py2.x iiiÝiit.ccs|]}t|ƒVqdS(N(tstr(t.0ti((s2/Users/kronuz/Development/pyScss/scss/scss_meta.pys 1ss %04d%02d%02dspyScss vs (t)sGerman M. Bravo (Kronuz)sgerman.mb@gmail.comshttp://github.com/Kronuz/pyScsss)http://github.com/Kronuz/pyScss/tarball/vtMITtpyScsst__main__sVERSION = sREVISION = sBUILD_INFO = sAUTHOR = sAUTHOR_EMAIL = sURL = sLICENSE = sPROJECT = N(iii(iÝii(t__doc__t VERSION_INFOt DATE_INFOtjointVERSIONtREVISIONt BUILD_INFOtAUTHORt AUTHOR_EMAILtURLt DOWNLOAD_URLtLICENSEtPROJECTt__name__(((s2/Users/kronuz/Development/pyScss/scss/scss_meta.pyt-s(          pyScss-1.1.5/scss/setup.py0000644000076500000240000000050411700501002016123 0ustar kronuzstaff00000000000000from distutils.core import setup, Extension setup(name='pyScss', version='1.1.1', description='pyScss', ext_modules=[ Extension( '_scss', sources=['src/_scss.c', 'src/block_locator.c', 'src/scanner.c'], libraries=['pcre'], optional=True ) ] ) pyScss-1.1.5/scss/src/0000755000076500000240000000000012107522130015210 5ustar kronuzstaff00000000000000pyScss-1.1.5/scss/src/.DS_Store0000644000076500000240000001400412104570565016706 0ustar kronuzstaff00000000000000Bud1†mardsclbogrammardsclbool  @€ @€ @€ @ E†DSDB `À @€ @€ @pyScss-1.1.5/scss/src/_speedups.c0000644000076500000240000004167711713615647017404 0ustar kronuzstaff00000000000000/* * pyScss, a Scss compiler for Python * SCSS blocks scanner. * * German M. Bravo (Kronuz) * https://github.com/Kronuz/pyScss * * MIT license (http://www.opensource.org/licenses/mit-license.php) * Copyright (c) 2011 German M. Bravo (Kronuz), All rights reserved. */ #include #include "block_locator.h" #include "scanner.h" /* BlockLocator */ staticforward PyTypeObject scss_BlockLocatorType; typedef struct { PyObject_HEAD BlockLocator *locator; } scss_BlockLocator; static int scss_BlockLocator_init(scss_BlockLocator *self, PyObject *args, PyObject *kwds) { char *codestr; int codestr_sz; self->locator = NULL; if (!PyArg_ParseTuple(args, "s#", &codestr, &codestr_sz)) { return -1; } self->locator = BlockLocator_new(codestr, codestr_sz); #ifdef DEBUG PySys_WriteStderr("Scss BlockLocator object initialized! (%lu bytes)\n", sizeof(scss_BlockLocator)); #endif return 0; } static void scss_BlockLocator_dealloc(scss_BlockLocator *self) { if (self->locator != NULL) BlockLocator_del(self->locator); self->ob_type->tp_free((PyObject*)self); #ifdef DEBUG PySys_WriteStderr("Scss BlockLocator object destroyed!\n"); #endif } scss_BlockLocator* scss_BlockLocator_iter(scss_BlockLocator *self) { Py_INCREF(self); return self; } PyObject* scss_BlockLocator_iternext(scss_BlockLocator *self) { Block *block; if (self->locator != NULL) { block = BlockLocator_iternext(self->locator); if (block->error > 0) { return Py_BuildValue( "is#s#", block->lineno, block->selprop, block->selprop_sz, block->codestr, block->codestr_sz ); } if (block->error > 0) { PyErr_SetString(PyExc_Exception, self->locator->exc); return NULL; } } /* Raising of standard StopIteration exception with empty value. */ PyErr_SetNone(PyExc_StopIteration); return NULL; } /* Type definition */ static PyTypeObject scss_BlockLocatorType = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "scss._BlockLocator", /* tp_name */ sizeof(scss_BlockLocator), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)scss_BlockLocator_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /* tp_flags */ "Internal BlockLocator iterator object.", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ (getiterfunc)scss_BlockLocator_iter, /* tp_iter: __iter__() method */ (iternextfunc)scss_BlockLocator_iternext, /* tp_iternext: next() method */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)scss_BlockLocator_init, /* tp_init */ }; /* Scanner */ static PyObject *PyExc_scss_NoMoreTokens; staticforward PyTypeObject scss_ScannerType; typedef struct { PyObject_HEAD Scanner *scanner; } scss_Scanner; static PyObject * scss_Scanner_rewind(scss_Scanner *self, PyObject *args) { int token_num; if (self->scanner != NULL) { if (PyArg_ParseTuple(args, "i", &token_num)) { Scanner_rewind(self->scanner, token_num); } } Py_INCREF(Py_None); return (PyObject *)Py_None; } static PyObject * scss_Scanner_token(scss_Scanner *self, PyObject *args) { PyObject *item; int i, is_tuple; long size; Token *p_token; int token_num; PyObject *restrictions; Pattern *_restrictions = NULL; int restrictions_sz = 0; if (self->scanner != NULL) { if (PyArg_ParseTuple(args, "i|O", &token_num, &restrictions)) { is_tuple = PyTuple_Check(restrictions); if (is_tuple || PyList_Check(restrictions)) { size = is_tuple ? PyTuple_Size(restrictions) : PyList_Size(restrictions); _restrictions = PyMem_New(Pattern, size); for (i = 0; i < size; ++i) { item = is_tuple ? PyTuple_GetItem(restrictions, i) : PyList_GetItem(restrictions, i); if (PyString_Check(item)) { _restrictions[restrictions_sz].tok = PyString_AsString(item); _restrictions[restrictions_sz].expr = NULL; restrictions_sz++; } } } p_token = Scanner_token(self->scanner, token_num, _restrictions, restrictions_sz); if (_restrictions != NULL) PyMem_Del(_restrictions); if (p_token == (Token *)SCANNER_EXC_BAD_TOKEN) { PyErr_SetString(PyExc_SyntaxError, self->scanner->exc); return NULL; } if (p_token == (Token *)SCANNER_EXC_RESTRICTED) { PyErr_SetString(PyExc_SyntaxError, self->scanner->exc); return NULL; } if (p_token == (Token *)SCANNER_EXC_UNIMPLEMENTED) { PyErr_SetString(PyExc_NotImplementedError, self->scanner->exc); return NULL; } if (p_token == (Token *)SCANNER_EXC_NO_MORE_TOKENS) { PyErr_SetNone(PyExc_scss_NoMoreTokens); return NULL; } if (p_token < 0) { PyErr_SetNone(PyExc_Exception); return NULL; } return Py_BuildValue( "iiss#", p_token->string - self->scanner->input, p_token->string - self->scanner->input + p_token->string_sz, p_token->regex->tok, p_token->string, p_token->string_sz ); } } Py_INCREF(Py_None); return (PyObject *)Py_None; } static PyObject * scss_Scanner_reset(scss_Scanner *self, PyObject *args, PyObject *kwds) { char *input = NULL; int input_sz = 0; if (self->scanner != NULL) { if (PyArg_ParseTuple(args, "|z#", &input, &input_sz)) { Scanner_reset(self->scanner, input, input_sz); } } Py_INCREF(Py_None); return (PyObject *)Py_None; } static PyObject * scss_Scanner_setup_patterns(PyObject *self, PyObject *patterns) { PyObject *item, *item0, *item1; int i, is_tuple, _is_tuple; long size; Pattern *_patterns = NULL; int patterns_sz = 0; if (!Scanner_initialized()) { is_tuple = PyTuple_Check(patterns); if (is_tuple || PyList_Check(patterns)) { size = is_tuple ? PyTuple_Size(patterns) : PyList_Size(patterns); _patterns = PyMem_New(Pattern, size); for (i = 0; i < size; ++i) { item = is_tuple ? PyTuple_GetItem(patterns, i) : PyList_GetItem(patterns, i); _is_tuple = PyTuple_Check(item); if (_is_tuple || PyList_Check(item)) { item0 = _is_tuple ? PyTuple_GetItem(item, 0) : PyList_GetItem(item, 0); item1 = _is_tuple ? PyTuple_GetItem(item, 1) : PyList_GetItem(item, 1); if (PyString_Check(item0) && PyString_Check(item1)) { _patterns[patterns_sz].tok = PyString_AsString(item0); _patterns[patterns_sz].expr = PyString_AsString(item1); patterns_sz++; } } } } Scanner_initialize(_patterns, patterns_sz); if (_patterns != NULL) PyMem_Del(_patterns); } Py_INCREF(Py_None); return (PyObject *)Py_None; } static int scss_Scanner_init(scss_Scanner *self, PyObject *args, PyObject *kwds) { PyObject *item, *item0, *item1; int i, is_tuple, _is_tuple; long size; PyObject *patterns, *ignore; Pattern *_patterns = NULL; int patterns_sz = 0; Pattern *_ignore = NULL; int ignore_sz = 0; char *input = NULL; int input_sz = 0; self->scanner = NULL; if (!PyArg_ParseTuple(args, "OO|z#", &patterns, &ignore, &input, &input_sz)) { return -1; } if (!Scanner_initialized()) { is_tuple = PyTuple_Check(patterns); if (is_tuple || PyList_Check(patterns)) { size = is_tuple ? PyTuple_Size(patterns) : PyList_Size(patterns); _patterns = PyMem_New(Pattern, size); for (i = 0; i < size; ++i) { item = is_tuple ? PyTuple_GetItem(patterns, i) : PyList_GetItem(patterns, i); _is_tuple = PyTuple_Check(item); if (_is_tuple || PyList_Check(item)) { item0 = _is_tuple ? PyTuple_GetItem(item, 0) : PyList_GetItem(item, 0); item1 = _is_tuple ? PyTuple_GetItem(item, 1) : PyList_GetItem(item, 1); if (PyString_Check(item0) && PyString_Check(item1)) { _patterns[patterns_sz].tok = PyString_AsString(item0); _patterns[patterns_sz].expr = PyString_AsString(item1); patterns_sz++; } } } } Scanner_initialize(_patterns, patterns_sz); } is_tuple = PyTuple_Check(ignore); if (is_tuple || PyList_Check(ignore)) { size = is_tuple ? PyTuple_Size(ignore) : PyList_Size(ignore); _ignore = PyMem_New(Pattern, size); for (i = 0; i < size; ++i) { item = is_tuple ? PyTuple_GetItem(ignore, i) : PyList_GetItem(ignore, i); if (PyString_Check(item)) { _ignore[ignore_sz].tok = PyString_AsString(item); _ignore[ignore_sz].expr = NULL; ignore_sz++; } } } self->scanner = Scanner_new(_patterns, patterns_sz, _ignore, ignore_sz, input, input_sz); if (_patterns != NULL) PyMem_Del(_patterns); if (_ignore != NULL) PyMem_Del(_ignore); #ifdef DEBUG PySys_WriteStderr("Scss Scanner object initialized! (%lu bytes)\n", sizeof(scss_Scanner)); #endif return 0; } static PyObject * scss_Scanner_repr(scss_Scanner *self) { /* Print the last 10 tokens that have been scanned in */ PyObject *repr, *tmp; Token *p_token; int i, start, pos; if (self->scanner != NULL && self->scanner->tokens_sz) { start = self->scanner->tokens_sz - 10; repr = PyString_FromString(""); for (i = (start < 0) ? 0 : start; i < self->scanner->tokens_sz; i++) { p_token = &self->scanner->tokens[i]; PyString_ConcatAndDel(&repr, PyString_FromString("\n")); pos = (int)(p_token->string - self->scanner->input); PyString_ConcatAndDel(&repr, PyString_FromFormat(" (@%d) %s = ", pos, p_token->regex->tok)); tmp = PyString_FromStringAndSize(p_token->string, p_token->string_sz); PyString_ConcatAndDel(&repr, PyObject_Repr(tmp)); Py_XDECREF(tmp); } } else { repr = PyString_FromString("None"); } return (PyObject *)repr; /* PyObject *repr, *tmp, *tmp2; Token *p_token; char *tok; int i, start, first = 1, cur, max=0, pos; if (self->scanner != NULL && self->scanner->tokens_sz) { start = self->scanner->tokens_sz - 10; repr = PyString_FromString(""); for (i = (start < 0) ? 0 : start; i < self->scanner->tokens_sz; i++) { p_token = self->scanner->tokens[i]; PyString_ConcatAndDel(&repr, PyString_FromString("\n")); pos = (int)(p_token->string - self->scanner->input); PyString_ConcatAndDel(&repr, PyString_FromFormat(" (@%d) %s = ", pos, p_token->regex->tok)); tmp = PyString_FromString(p_token->string); PyString_ConcatAndDel(&repr, PyObject_Repr(tmp)); Py_XDECREF(tmp); } start = self->scanner->tokens_sz - 10; for (i = (start < 0) ? 0 : start; i < self->scanner->tokens_sz; i++) { p_token = self->scanner->tokens[i]; cur = strlen(p_token->regex->tok) * 2; if (cur > max) max = cur; } tok = PyMem_New(char, max + 4); repr = PyString_FromString(""); for (i = (start < 0) ? 0 : start; i < self->scanner->tokens_sz; i++) { p_token = self->scanner->tokens[i]; if (!first) PyString_ConcatAndDel(&repr, PyString_FromString("\n")); pos = (int)(p_token->string - self->scanner->input); if (pos < 10) PyString_ConcatAndDel(&repr, PyString_FromString(" ")); if (pos < 100) PyString_ConcatAndDel(&repr, PyString_FromString(" ")); if (pos < 1000) PyString_ConcatAndDel(&repr, PyString_FromString(" ")); PyString_ConcatAndDel(&repr, PyString_FromFormat("(@%d) ", pos)); tmp = PyString_FromString(p_token->regex->tok); tmp2 = PyObject_Repr(tmp); memset(tok, ' ', max + 4); tok[max + 3 - PyString_Size(tmp2)] = '\0'; PyString_ConcatAndDel(&repr, PyString_FromString(tok)); PyString_ConcatAndDel(&repr, tmp2); Py_XDECREF(tmp); PyString_ConcatAndDel(&repr, PyString_FromString(" = ")); tmp = PyString_FromString(p_token->string); PyString_ConcatAndDel(&repr, PyObject_Repr(tmp)); Py_XDECREF(tmp); first = 0; } PyMem_Del(tok); } else { repr = PyString_FromString("None"); } return (PyObject *)repr; */ } static void scss_Scanner_dealloc(scss_Scanner *self) { if (self->scanner != NULL) Scanner_del(self->scanner); self->ob_type->tp_free((PyObject*)self); #ifdef DEBUG PySys_WriteStderr("Scss Scanner object destroyed!\n"); #endif } static PyMethodDef scss_Scanner_methods[] = { {"reset", (PyCFunction)scss_Scanner_reset, METH_VARARGS, "Scan the next token"}, {"token", (PyCFunction)scss_Scanner_token, METH_VARARGS, "Get the nth token"}, {"rewind", (PyCFunction)scss_Scanner_rewind, METH_VARARGS, "Rewind scanner"}, {"setup_patterns", (PyCFunction)scss_Scanner_setup_patterns, METH_O | METH_STATIC, "Initialize patterns."}, {NULL, NULL, 0, NULL} /* Sentinel */ }; static PyTypeObject scss_ScannerType = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "scss.Scanner", /* tp_name */ sizeof(scss_Scanner), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)scss_Scanner_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)scss_Scanner_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ "Scanner object.", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter: __iter__() method */ 0, /* tp_iternext: next() method */ scss_Scanner_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)scss_Scanner_init, /* tp_init */ }; /* Python constructor */ static PyObject * scss_locate_blocks(PyObject *self, PyObject *args) { scss_BlockLocator *result = NULL; result = PyObject_New(scss_BlockLocator, &scss_BlockLocatorType); if (result) { scss_BlockLocator_init(result, args, NULL); } return (PyObject *)result; } /* Module functions */ static PyMethodDef scss_methods[] = { {"locate_blocks", (PyCFunction)scss_locate_blocks, METH_VARARGS, "Locate Scss blocks."}, {NULL, NULL, 0, NULL} /* Sentinel */ }; /* Module init function */ PyMODINIT_FUNC init_speedups(void) { PyObject* m; scss_BlockLocatorType.tp_new = PyType_GenericNew; if (PyType_Ready(&scss_BlockLocatorType) < 0) return; scss_ScannerType.tp_new = PyType_GenericNew; if (PyType_Ready(&scss_ScannerType) < 0) return; BlockLocator_initialize(); Scanner_initialize(NULL, 0); m = Py_InitModule("_speedups", scss_methods); Py_INCREF(&scss_BlockLocatorType); PyModule_AddObject(m, "_BlockLocator", (PyObject *)&scss_BlockLocatorType); Py_INCREF(&scss_ScannerType); PyModule_AddObject(m, "Scanner", (PyObject *)&scss_ScannerType); PyExc_scss_NoMoreTokens = PyErr_NewException("_speedups.NoMoreTokens", NULL, NULL); Py_INCREF(PyExc_scss_NoMoreTokens); PyModule_AddObject(m, "NoMoreTokens", (PyObject *)PyExc_scss_NoMoreTokens); } pyScss-1.1.5/scss/src/_speedups.o0000644000076500000240000021404412034740571017376 0ustar kronuzstaff00000000000000Êþº¾t ˆ$ Îúíþð ˆ S S__text__TEXTE (Y™€__debug_info__DWARFE ÖQð]S__debug_abbrev__DWARF*'0__debug_aranges__DWARF3,?2__debug_macinfo__DWARF3,?2__debug_line__DWARF3,º?2ˆ`__debug_loc__DWARFí/4ù5`°__debug_pubtypes__DWARF!5t-;__debug_str__DWARF•51 ¡;__debug_ranges__DWARFÆBÒH__data__DATAÈBøÔHf__cstring__TEXTÀDaÌJ__bss__DATAS__apple_names__DWARF!Fô-Lèf$__apple_objc__DWARFH$!N__apple_namespac__DWARF9H$EN__apple_types__DWARF]H iNhœ__debug_inlined__DWARFbQnW__pointers__IMPORTiQuW__debug_frame__DWARF€QœŒWèl dm7øo  P%PmU‰å‹Eÿ]ÃU‰åSWVƒìè^‹E‹@…Àt@‰$èÕÿÿÿƒ8~3‹H‹P‹x ‹X‹@‰D$‰\$‰|$ ‰T$‰L$†¨D‰$èŸÿÿÿ닆UQ‹‰$èÿÿÿ1ÀƒÄ^_[]ÃU‰åSWVƒìè_‹·êP‰·ÙB‡=B‰$èZÿÿÿ…Àˆç‰·CŸC‰$è>ÿÿÿ…ÀˆËè1ÿÿÿÇD$Ç$èÿÿÿ‡ÅC‰D$‡;D‰$ÇD$õÇD$ ÇD$èíþÿÿ‰Æÿ‡=B‡=B‰D$‡ED‰D$‰4$èÉþÿÿÿ‡C‰\$‡SD‰D$‰4$è­þÿÿ‡[D‰$ÇD$ÇD$èþÿÿ‰‡‘Rÿ‹‡‘R‰D$‡rD‰D$‰4$èkþÿÿƒÄ^_[]ÃU‰åVƒìèX€A‰$èHþÿÿ‰Æ…öt‹E ‰D$‰4$ÇD$è‰ðƒÄ^]ÃU‰åVƒì$èX‹uÇFMô‰L$ Mø‰L$€CC‰D$‹E ‰$èéýÿÿ‰Á¸ÿÿÿÿ…Ét‹Eø‹Mô‰L$‰$èÌýÿÿ‰F1ÀƒÄ$^]ÃU‰åVP‹u‹F…Àt‰$èªýÿÿ‹F‹€ ƒÄ^]ÿàU‰åSWVƒì,èZ‹M‹A…À„‹¸Ð…ÿ„ ‚ZC‰$‰Ë‰Uäè\ýÿÿ‰EðƒÇö1Ò…ÿ‰þHò‰uì‹K;±ÐÎ…ÿI×kú ƒÇ‹Uä‚[C‰Eè‚]C‰E䋱؋Eè‰$è ýÿÿ‰D$Eð‰$èûüÿÿ‹L>ø‹D>ü‹S+‚ä‹ ‰L$‰D$‹Eä‰$èÕüÿÿ‰D$]ð‰$èÆüÿÿ‹D>ü‹ >‰L$‰$è³üÿÿ‰Æ‰4$è©üÿÿ‰D$‰$èüÿÿ…öt ÿu ‹F‰4$ÿPƒÇ ‹]‹K‹Eì@‰Eì;ÐŒUÿÿÿ‹EðƒÄ,^_[]ÂnC‰$èWüÿÿ‰EðëåU‰åSWVƒìLèXÇEèÇEä‹MÇAMä‰L$Mè‰L$Mì‰L$ Mð‰L$€A‰D$‹E ‰$èúûÿÿ‰Á¸ÿÿÿÿ…É„¥èæûÿÿÇEÌ…ÀÇEÐÇEØ…z‹Eð‹H‹QT‰Ñá‰MÈ”Á÷ÂuÇEЄÉÇEØ…3ƒ}Èt ‰$è†ûÿÿë‰$è|ûÿÿ‰Ç‰}ÜÇEØÿªªª ¸w kÇ ‰$èXûÿÿ…ÿ‰EÐéë‰EÐ1À‰Eà‹Eðƒ}Èt‹Mà‰L$‰$è,ûÿÿë‹Mà‰L$‰$èûÿÿ‰Æ‹F‹PT‰Ð%”Á÷Âu„É…‰…Àt$‰4$ÇD$èåúÿÿ‰Ç‰4$ÇD$èÓúÿÿë"‰4$ÇD$èÁúÿÿ‰Ç‰4$ÇD$è¯úÿÿ‹OöAWt3‹HöAWt*‰<$‹uØkþ ‰EÔèŒúÿÿ‹]Љ;‹EÔ‰$è{úÿÿ‰D;F‰uØ‹}Ü‹Eà@‰Eà9Ç…ÿÿÿ‹E؉D$‹EЉ$èOúÿÿ‹Eì‹H‹QT‰Ñá‰Mà”Á÷Âu „ɾ…Žƒ}àt ‰$èúÿÿë‰$è úÿÿ‰Ç1öÿªªª ÇEÌwkÇ ‰$èíùÿÿ‰EÌ…ÿ~Q‰}܉÷‹Eìƒ}àt‰|$‰$èÌùÿÿë ‰|$‰$è¾ùÿÿ‹HöAWt‰$kÞ èªùÿÿ‹M̉ÇDFG9}Üu´‹Eè‹Mä‰L$‰D$‰t$ ‹ủt$‹E؉D$‹}Љ<$èjùÿÿ‹M‰A‰ø…Àt‰$èVùÿÿ1À…öt ‰4$èHùÿÿ1ÀƒÄL^_[]ÃU‰åWVƒì è^ÇEôÇEð‹}ƒt@‹E Mð‰L$ Mô‰L$Žû>‰L$‰$èöøÿÿ…Àt‹G‹Mô‹Uð‰T$‰L$‰$èÙøÿÿ‹†ªJÿƒÄ ^_]ÃU‰åSWVƒì<è^‹]ƒ{„©‹E Mì‰L$ Mð‰L$Ž|>‰L$‰$è‹øÿÿ…À„~‰uÜ‹Eì‹H‹QT‰Ñá‰Mä”Á÷ÂuÇEè„É¿…”ƒ}ät ‰$è?øÿÿë‰$è5øÿÿ‰Æ1ÿþªªª ¸w kÆ ‰$èøÿÿ…ö‰EèëT‰uà‰Eè‰û‹Eìƒ}ät‰\$‰$èó÷ÿÿë ‰\$‰$èå÷ÿÿ‹HöAWt‰$k÷ èÑ÷ÿÿ‹Mè‰1ÇD1GC9]àu´‹]‹C‹Mð‰|$ ‹uè‰t$‰L$‰$èœ÷ÿÿ‰Ç…öt‰4$èŽ÷ÿÿGƒøwC‹MÜ‹„ÈÈÿà‹-J‹‹K‰L$‰$èa÷ÿÿ1Àë`‹%Jëã‹ØK‰$èG÷ÿÿ1ÀëF‹s‹‹W‰Ð+†ä‹1‹O‰L$‰T$‰t$ Á‰L$‰D$‹EÜ€€>‰$è÷ÿÿ닆5JÿƒÄ<^_[]Ãg_DDU‰åWVƒìè^‹}ƒt2‹E Mô‰L$Ž•<‰L$‰$è±öÿÿ…Àt‹G‹Mô‰L$‰$è›öÿÿ‹†PHÿƒÄ^_]ÃU‰åSWVƒì,èX‰EÜèuöÿÿ…À…x‹E ‹@‹HT‰È%‰Eè”À÷Áu<uÇD$Ç$è7öÿÿé=ƒ}èt ‹E ‰$è!öÿÿë ‹E ‰$èöÿÿ‰Æ1ÿþªªª ¸w kÆ ‰$èøõÿÿ‰Eä…öŽÝ‰uà‰þƒ}èt‰t$‹E ‰$èÓõÿÿë‰t$‹E ‰$èÂõÿÿ‰Ã‹C‹PT‰Ð%”Á÷Âu„É…†‰uð…Àt$‰$ÇD$è‰õÿÿ‰Æ‰$ÇD$èwõÿÿë"‰$ÇD$èeõÿÿ‰Æ‰$ÇD$èSõÿÿ‹NöAWt-‹HöAWt$‰4$k÷ ‰Eìè3õÿÿ‹]ä‰3‹Eì‰$è"õÿÿ‰D3G‹uðF9uà…(ÿÿÿ‰|$‹uä‰4$èõÿÿ…öt‰4$èõôÿÿ‹EÜ‹€÷GÿƒÄ,^_[]ÃU‰åVP‹u‹F…Àt‰$èËôÿÿ‹F‹€ ƒÄ^]ÿàÒ LXž#§u*¸º5ÀªãLS]e 2 '}B ^` R„a# Xvb# v·¸L v·ÉvΉé—.ð¡nû°U ·v v·Xv, ÉG}R}R ÷X‚ $„ƒ# 5v„# 8v…# ;‰†#  H‰‡# Nˆ# ev‰# n·Œ# vÄ#  }äŽ#$ ƒ'#( ·B#, ¾“#0 ÂM”#8 Òv•#< ÖU˜#@ Üa™#C âœ#D ævŸ#L ï #Pmÿ¡¢ v­v²È3 ÉÙê4 vÉû06 v"3G8 DPW9 art† ‚˜Á‡PÙ… v³¿ˆ vÏÏÔåJŠœÛ mwä# wå# ‹wæ# —wç#  ¡wè# ®wé# ¸ê# ͨë# ã¨ì#  ï¨í#$ ûÄî#( ¨ï#, wð#0 "wñ#4 ,wò#8 3wó#< :wô#@ @êõ#D S¨ö#H Z¨÷#L b¨ø#P k¨ù#T r¨ú#X ywü#\ ˆwý#` œwþ#d °wÿ#hÂw#l×#pèw#túw#x w#|w#€*w#„8w #ˆHw #ŒWw #ow #”†¨#˜õV Ags¸‰ Aƒ”Ô AA¤ºòŽ vAÊà‘ vAAð -’3N×(®x#Àw#Ê™#á™# é¿#å# #B#Yw# k™#$&}Ì vÝóÅ“ !x"#§w##´ø$#Ó%9 #JVì:r5ó)7· AA„šTšužA AµºË”ŸÉ AAÛàö² AR %4¤ η¥# Ò¦# ÖA§# ÚA¨#  ãvª# ìv«# ñɬ# øµ­# þµ®#  µ¯#$  °#( ·²#0 0³Ï vÚ vß õ :µÚ   Y¶'CŸ(#cª)#…Ð*#¡û+# Áú ,#H -#" k.ˆ v·™ ª •Ø v¯ ·º Ð ŸÙ và ö Ä;Pê<P=r* F% X&# " '# 6v(# ?X*# * ]t ·  | v·  ¶ ‡ š sÉ # x•  # ƒ» # ŽÉ#  ’·#Æ ˜Ã>óÝ?ó @ ×AC T  B ×e { # A·Œ ” 3 1Ž › ÄD”AE#Ë×E#ÓAE#ÛXF# èAG#õAG#jK#ÍL#ïM# %N#$<8O#(OUP#,`bT#0ŸØU#4EV#8ä[Z#<õ[#@ýU\#Dg]#Hs^#L6” a#Py#d#T‚Xf#X‰Õ j#\¬Äm#`µû q#dÐAt#hâ x#lö y#po |#tRz }#xi ~#|¦×#€®€#„¶ #ˆÐ+ ‚#ŒêAƒ#ø7 „#” Y …#˜ € †#œ+ ™ ‡# < Ĉ#¤E ‰#¨N Š#¬U ‹#°^ Œ#´l #¸x jŽ#¼ ¥ ‘#À¬ § j ”Ak# Ë×k#ܯ l|‰S* F,$R¸ /PD¬ Ö ›Å MÉŒC$Rã kÁpDø M_ÈB 9˜ UÓ 9˜‘LRÇ ™ v# Y v# Ÿ É# § v#  : É# N v#̲  - À# 1 É#È : É#Ì B É#Ð N v#Ô Y v#Ø ` v #Ü d L!#à j v"#ä p v##è u É$#ì z É%#ð  É&#ô „ É'#ø ‰ É(#ü É)#€ “ +*#„6¸ +K  ”A# Ë×# % V#[Å × @ }UÓ @˜‘}“ Bò  }U€Ø  õÝUÓ õ‘ Ú õ&ªÝß ÷˜9! vÝ?U"Ó ˜LÚ ‘ æ ‘í?#: É‘x#N v‘t#: É‘x#: É‘x#: É‘x#: É‘x#: É‘x#N v‘t#N v‘t#N v‘t#N v‘t#N v‘t* v®ÂU Ó ÐlÚ ‘ æ ‘±Â$~ ‘p$ý ‘l$œ "É‘h$“ #v‘d$ý ‘l$ý ‘l$ý ‘l$ý ‘l$ý ‘l$œ "É‘h$œ "É‘h$œ "É‘h$œ "É‘h$œ "É‘h$“ #v‘d$“ #v‘d$“ #v‘d$“ #v‘d$“ #v‘dr v ó !vAÎ  `Ö #µÀ vÓÛ à >æ Qì `p%ö v%ÿ v7±$~ ‘p$~ ‘p$~ ‘p$~ ‘p$~ ‘ppŸ$~ ‘p¨Ÿ¼$~ ‘p$~ ‘p$~ ‘p$~ ‘p$~ ‘pák$ý ‘lke$ý ‘l$ý ‘l$ý ‘l$ý ‘l$ý ‘l!< ôt  UÓ ô‘"~ ôV†  r ûv+Ö ø#iì ú`|À ÷v²Û öÑà öïæ ö&ö ÷v&ÿ ÷v!X ” t U"Ó ”Ð"Ú ”- t # –v‘t9 e S e # –v‘t# –v‘t# –v‘t# –v‘t# –v‘t!l ¢6 U"Ó ¢Ðì"Ú ¢CH # ªv‘p#e «‘l ­vÁÖ ¦#V# ¬`iÀ ¥vµÛ ¤ÔÆ ¨§ç&ö ¥vXû€û# ªv‘p# ªv‘p# ªv‘p# ªv‘p# ªv‘p#e «‘l#e «‘l#e «‘l#e «‘l#e «‘l·D#e «‘lçDø>#e «‘l#e «‘l#e «‘l#e «‘l#e «‘l! äÂ6U"Ó äЛ"Ú ä®æ ä‘Å6#œ æÉ‘t#“ çv‘pí''#œ æÉ‘t#œ æÉ‘t#œ æÉ‘t#œ æÉ‘t#œ æÉ‘t#“ çv‘p#“ çv‘p#“ çv‘p#“ çv‘p#“ çv‘p’ \f®U Ó \Ðrx®$» _‘p$» _‘p$» _‘p$» _‘p$» _‘p$» _‘p‰ av›À av®¢ avä _÷%Æ `§'¤ ¶?fU Ó ¶Ð_(¹ - E U"Ó -˜!+       É#  É# ##$ U` ! H `"# N É## U v$#j_ %œ' r v(# ~ e)#¬‡ *Ïì, - À-# ó v.#È ý e/#Ì , v0#Ð 6 v1#Ô A §2#Ø e Ú3#Ü “ v4#à œ É5#ä ¢ v6#èߦ 7ƒ  ”AŽ# Ë׎# ë Ž#“® Å%Rá $> I: ; I: ;&II' I  : ; I: ; 8 2  I' < $ > I!I/  : ;  I: ;8 2  : ; : ;4I: ;  4I: ; .: ; ' I? @ : ; I  : ;  4: ; I.: ;' ? @ 4: ;I.: ;' I@ : ;I : ;I!.: ; ' I@ ": ; I#4: ; I $4: ;I %4: ;I&4: ; I'.: ;' @ (.: ; ' @ ¶Öû /System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7/usr/include._speedups.cobject.hstdio.hmethodobject.hdescrobject.hblock_locator.hscanner.h9 g/3 # u„ Y3"³‚ ?Éõ»õY>2sffZgZ$/­O‚  Ëh?›|‚ ö +mf ƒt„£ò & „Wvg!×’!g’I!É $!K ;LxÈCºò ©§.  </  ="=%./ž=È ­=t.6ÉK.!5!ó$!%gåwž ¬#=­.,ž» äבt.3Ö»‘ƒ  X7ŸJ¥Œ‚ =! »ó†ƒ³t   ó(=#.4ž»È ­t.;Ö»,‘ƒ  ‚#„]¢† ' >„´‚ »‘#ƒØt 'óóäpºX/È»È ×.6Éu.!5!ó$!%=åwJ /„­›~‚ ƒt„+?P•VÕPÅÕVÝ9V?cVfœQœSzSªÍW³¿V¿ulŠPŠ®ul#POtVÄŠŠVŸuXŸÂÄeeeVk®ÕQ!YuLYdQd€uL€ºV†¬W÷W¨””™P™u`ffkWçÿViVBKPAQWZoPoÂuTtwuPw‰S‰ÂuPÂ'W PE>>>WG 6¹S¹ÃuXÃÃSÃGuXGŽS£«S½ûS6uPÍëVÚÜPçëP/2uh2=Q=TuhTrVç??DS/PfzW½ûW e W O Pƒ ã ã æ Wð  t ™ Pð  Vð  WÍ Ð udÐ â Sâ  ud ç ç ð V@ X S` Ð S ­ V¶ È PÈ  ul B VpÖm__sFILEÆ PyGetSetDef bufferinfoÜ_object¬ _typeobject* PyMethodDef__sbufApple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)_speedups.c/usr/local/www/dubalu/libs/scss/srcPyExc_scss_NoMoreTokensob_refcntlong int__darwin_ssize_tssize_tPy_ssize_tob_typeob_sizetp_namechartp_basicsizetp_itemsizetp_deallocdestructortp_printint_punsigned char_r_w_flagsshort_file_bf_base_size__sbuf_lbfsize_cookie_close_read_seeklong long int__int64_t__darwin_off_tfpos_t_write_ub_extra__sFILEX_ur_ubuf_nbuf_lb_blksize_offset__sFILEFILEprintfunctp_getattrgetattrfunctp_setattrsetattrfunctp_comparecmpfunctp_reprreprfunctp_as_numbernb_addbinaryfuncnb_subtractnb_multiplynb_dividenb_remaindernb_divmodnb_powerternaryfuncnb_negativeunaryfuncnb_positivenb_absolutenb_nonzeroinquirynb_invertnb_lshiftnb_rshiftnb_andnb_xornb_ornb_coercecoercionnb_intnb_longnb_floatnb_octnb_hexnb_inplace_addnb_inplace_subtractnb_inplace_multiplynb_inplace_dividenb_inplace_remaindernb_inplace_powernb_inplace_lshiftnb_inplace_rshiftnb_inplace_andnb_inplace_xornb_inplace_ornb_floor_dividenb_true_dividenb_inplace_floor_dividenb_inplace_true_dividenb_indexPyNumberMethodstp_as_sequencesq_lengthlenfuncsq_concatsq_repeatssizeargfuncsq_itemsq_slicessizessizeargfuncsq_ass_itemssizeobjargprocsq_ass_slicessizessizeobjargprocsq_containsobjobjprocsq_inplace_concatsq_inplace_repeatPySequenceMethodstp_as_mappingmp_lengthmp_subscriptmp_ass_subscriptobjobjargprocPyMappingMethodstp_hashhashfunctp_calltp_strtp_getattrogetattrofunctp_setattrosetattrofunctp_as_bufferbf_getreadbufferreadbufferprocbf_getwritebufferwritebufferprocbf_getsegcountsegcountprocbf_getcharbuffercharbufferprocbf_getbufferbufobjlenitemsizereadonlyndimformatshapestridessuboffsetssmalltableinternalbufferinfoPy_buffergetbufferprocbf_releasebufferreleasebufferprocPyBufferProcstp_flagstp_doctp_traversevisitproctraverseproctp_cleartp_richcomparerichcmpfunctp_weaklistoffsettp_itergetiterfunctp_iternextiternextfunctp_methodsml_nameml_methPyCFunctionml_flagsml_docPyMethodDeftp_membersPyMemberDeftp_getsetnamegetgettersetsetterdocclosurePyGetSetDeftp_basetp_dicttp_descr_getdescrgetfunctp_descr_setdescrsetfunctp_dictoffsettp_initinitproctp_allocallocfunctp_newnewfunctp_freefreefunctp_is_gctp_basestp_mrotp_cachetp_subclassestp_weaklisttp_deltp_version_tagunsigned int_typeobject_objectPyObjectscss_methodsscss_ScannerTypePyTypeObjectscss_Scanner_methodsscss_BlockLocatorTypescss_BlockLocator_iterlocatorexc_codestrcodestrcodestr_ptrcodestr_szlinenoparinstrdepthskipthininitsafelosestartendblockerrorselpropselprop_szBlockBlockLocatorscss_BlockLocatorscss_BlockLocator_iternextinit_speedupsscss_locate_blocksscss_BlockLocator_initscss_Scanner_initscss_Scanner_setup_patternsscss_Scanner_rewindscss_Scanner_tokenscss_Scanner_resetscss_Scanner_reprscss_Scanner_deallocscss_BlockLocator_deallocselfmargsresultkwdsscannerignore_szignoretokexprpatternreal_pcrepcrePatterntokens_sztokens_bsztokensregexstringstring_szTokenrestrictionspatterns_szpatternsRestrictioninput_szinputposScannerscss_Scannerrepritmpp_token_ignoresizeitemitem0item1_patternsis_tuple_is_tupletoken_numrestrictions_sz_restrictionsçE  ëúE Ý/E ?fëBDÿÿÿÿÿÿÿÿEFÿÿÿÿGHÎå¯[íŸàõ*/‚鿇s‚«zDt/­î7ê(ÎÖÄ8ŸæÕ¬¨^B%㊰+€kÀäLgUïœÿ­ÕðZKÀ:Éãq«ü v´6—Ï’Öá~zÍ×™s.\C;²žÊ¨ þ0†¹PÁöý/.œ|¥MýqtÞFÔÍ“<²'É5ô˜Ò±&½-¶à‘J{H¡Hˆ.ê°¼êpüÒÀD¹hvÜ·^å܆…€IÊð5ÿp÷SðpìÉë{4ïwÎ’0€ˆ ì=, ÑÁ¯»‚ e3›´>¬Ôœ›üžŠ©œPŸ‡ÿÛ•Üsªÿ¤Œyq5îµ”˜](r°ìñ췇Š ‚A°óÊSØÜ÷\w°oæ ·¦Éc •|*­H—üˆ-þ"‰Æ¤7#«¥²„|áPÜG §Ëù4GZm€“¦¹Ìßò+>QdwаÃÖéü"5H[n”§ºÍàó,?Rex‹ž±Ä×êý#=Pcv‰œ¯ÂÕèû!4GZm€“¦¹ÌßòÝ+ ‡ Ïà ¦ ƒ0Ï —ðTŸ* ĸ5•¯ ê %  NB‰$V$ U‰é$Á÷m 7 Ó9§ Ü® ÅͰ ¯  jŽ ¥ $ò¿0_ œtwg§*¸x Y ԙЇ» Ù¨¡û^Åøkˆ  v$ž#$› ¬ ²û# € ŸÕ F* $}Ì-|• ÀA:ú ïì[Y )sG8Ö MšÆ 3 ™ å² +Äû ãL$WUJêuª¸ Kÿ¢”Ð'}$ÿÿÿÿ| ˆ A„B  sA„B F†‡ƒ} A„B F†‡ƒ@A„B D†ÝbA„B D†?'A„B B†fHA„B F†‡ƒ®A„B F†‡ƒÂtA„B E†‡6ÕA„B F†‡ƒ XA„B E†‡t ªA„B F†‡ƒ 'A„B B†1   ¤yQ¡‚   û / Ú # É # ©  —  … ( s ( :  ) (  è  Û ) Å / ‡ 0 g ¤yQ¡) a 3 K  ? ¤¾E¡) ý¤yQ¡Dõ, í¤ÄE¡Dµ ­¤S¡D¥¤iQ¡D› ФqQ¡Dn `4 +#  ( ã Ç ½) q e¤ÀE¡D)¤yQ¡Ï#2  ú¤ÊE¡Ï´ ¦ ’1 R# > 0(  ñ ç) ­/ # p# M ; )( ( á Ð( ¤ € v) 0  ó¤LE¡¼¥& ¤âE¡t_$ S" I' 6$ '% $ ò& Þ¤ÑE¡tÕ¤ÏE¡t & “¤ÎE¡tR. 0  ¤,E¡éÑ´5 ¬¤ÈB¡©‘! …¤ýD¡‹{¤S¡‹s¤S¡‹m U¤æD¡‹O! C¤ÞD¡‹9¤ŒC¡‹3! '¤ÐD¡‹¤ÈB¡‹¤ÈB¡‹- ï¤ÆD¡‹å¤PD¡‹ß/ Ë ¾+ ¶¤ŒC¡‹°¤ŒC¡‹¢+ š¤ÈB¡‹”¤ÈB¡‹Ž¤uQ¡‹o e¤mQ¡], U¤ÀD¡' ñíÎÊúöUQLH'#ð싆‚okÚÖÑÍGCÀ¼·³ œwsâÞº¶VRMI51ÝÙÔм¸hdš–a]¢žlhFBõñêæÇ§– … g I   ä%! óïàÜÕѾ¶²¢ž—“‹‡€|miZVFB;7/+ öòëçØÔÅÁ¹µ¦¢š–‹ƒxtmiZVGC40)%û÷ðìÜØÑÍÅÁ²®Ÿ›‹‡€|tp`\UQB>/+$ úöîêãß×ÓÄÀ¹µ¦¢š–‹ƒpl\XQMEA1-%! û÷èäÔÐÉŽ¹²®Ÿ›Œˆ}vrc_PL=9*&ä ÜØ Ô ÌÈ Ä ¼¸ ´ ¬¨ ” Œˆ X8  ðÜÐ ”plX  ФH¡!F̤õG¡!FȤåG¡!FĤÕG¡!FÀ¤ÅG¡!F¼¤µG¡!F¸¤¥G¡!F´¤•G¡!F°¤…G¡!F¬¤uG¡!F¨¤eG¡!F¤¤UG¡!F ¤EG¡!Fœ¤5G¡!F˜¤%G¡!F”¤G¡!F¤G¡!FŒ¤õF¡!F0¤OQ¡]H,¤ÝV?lf®’¦6º Ït ì  pDj} b‡5 ûØ[At¤ç»Èĉ÷AX,mÖ­·yL´ ˜ #R2ìÊ_scss_BlockLocator_iter_scss_BlockLocator_iternext_BlockLocator_iternext_Py_BuildValue_PyErr_SetNone_init_speedups_PyType_Ready_BlockLocator_initialize_Scanner_initialize_Py_InitModule4_PyModule_AddObject_PyErr_NewException__PyObject_New_PyArg_ParseTuple_BlockLocator_new_Scanner_del_PyString_FromString_PyString_ConcatAndDel_PyString_FromFormat_PyString_FromStringAndSize_PyObject_Repr_Scanner_initialized_PyTuple_Size_PyList_Size_PyMem_Malloc_PyTuple_GetItem_PyList_GetItem_PyString_AsString_Scanner_new_PyMem_Free_Scanner_reset_Scanner_token_PyErr_SetString_Scanner_rewind_BlockLocator_del_PyExc_NotImplementedError_PyExc_StopIteration_PyExc_SyntaxError_PyType_GenericNew__Py_NoneStruct_scss_BlockLocatorType_scss_ScannerType_scss_methods_PyExc_scss_NoMoreTokens_scss_locate_blocks_scss_BlockLocator_init_scss_Scanner_dealloc_scss_Scanner_repr_scss_Scanner_init_scss_Scanner_reset_scss_Scanner_token_scss_Scanner_rewind_scss_Scanner_setup_patterns_scss_BlockLocator_dealloc_scss_Scanner_methodsÏúíþð ˆ____text__TEXTÔ  fw€__debug_info__DWARFÔ ] äØiS__debug_abbrev__DWARF1+A2__debug_aranges__DWARFI-Y4__debug_macinfo__DWARFI-Y4__debug_line__DWARFI-¯Y4pl__debug_loc__DWARFø0‰ 8xlþ__debug_pubtypes__DWARF=t‘D__debug_str__DWARFõ=1 E__debug_ranges__DWARF&K6R__data__DATA0Kð@Rht__cstring__TEXT Oa0V__bss__DATA___apple_names__DWARFPô‘W@u$__apple_objc__DWARFuR$…Y__apple_namespac__DWARF™R$©Y__apple_types__DWARF½R ÍY`vœ__debug_inlined__DWARFÂ[Òb__compact_unwind__LDÉ[Ùb@{__eh_frame__TEXTÐ\@àc h€{c°t P88>%UH‰åHÿH‰ø]ÃUH‰åH‹H…ÿt èƒ8H‹H‹8è1À]ÃD‹H L‹@‹HH‹P‹pH=0À]éUH‰åSPH‹H‰8H=è…ÀxH‹H‰8H=è…ÀyHƒÄ[]Ãè1ÿ1öèH=H51Ò1ÉA¸õèH‰ÃHÿH5HH‰ßèH5HHÿH‰ßèH=1ö1ÒèH5H‰HÿH‹H‰ßHƒÄ[]éUH‰åAVSI‰öH=èH‰ÃH…Ût H‰ßL‰ö1ÒèH‰Ø[A^]ÃUH‰åSHƒìH‰ûHÇCHHUðHMìH‰÷H‰Æ0Àè‰Á¸ÿÿÿÿ…Ét‹uìH‹}ðèH‰C1ÀHƒÄ[]ÃUH‰åSPH‰ûH‹{H…ÿtèH‹CH‰ßHƒÄ[]ÿ @UH‰åAWAVAUATSPI‰ýI‹EH…À„ö‹˜Ø…Û„èH=èH‰EЃÃö…ÛA¾DIóI‹MD;±Ø©L}ÐH‹™àH=èL‰ÿH‰ÆèIcÆL$@B‹tãI‹E+°øJ‹ãH‹H=0ÀèL‰ÿH‰ÆèJctãJ‹|ãèH‰ÃH‰ßèL‰ÿH‰ÆèH…ÛtHÿ u H‹CH‰ßÿP0I‹MAÿÆD;±ØŒ_ÿÿÿH‹EÐHƒÄ[A\A]A^A_]ÃH=èH‰EÐëßUH‰åAWAVAUATSHƒìXH‰}ˆHÇEÀÇE¼HÇGHHUÐHMÈLEÀLM¼H‰÷H‰Æ0Àè‰Á¸ÿÿÿÿ…É„ºè1ÉH‰M°HÇE …À»A¼…lH‹}ÐH‹GH‹ˆ¨H‰ÈH%H‰E˜”À÷Áu„Àt 1ÛE1äé,Hƒ}˜tèëèI‰ÆE1ÿH¸UUUUUUUI9Æ»wJõH<@èH‰ÃE1äM…öŽßL‰uH‰]¨A¾H‹}ÐHƒ}˜t L‰þèëL‰þèH‰ÃH‹CH‹¨H‰ÐH%”Á÷Âu„ÉuzH‰ß1öH…ÀtèI‰ÇH‰ß¾èëèI‰ÇH‰ß¾èI‰ÅI‹Gö€«t4I‹Eö€«t'L‰ÿèMcäOI‹D$ö€«t0L‰÷èL‹mÈMcíOtmH‹]¸J‰óL‰çèJ‰DóAÿÅL‰mÈL‹uÐIcßAÿÇH;]°ŒÿÿÿH‹]¸H‰ßH‹uÈèH…ÛtH‰ßèH‹HÿHƒÄ([A\A]A^A_]ÃUH‰åSPH‰ûH‹{H…ÿtèH‹CH‰ßHƒÄ[]ÿ @Y  LXž'§u.¸º9ÀªãPW6ai 2 'B ^` Rˆa# Xzb# z»¼P z»ÍzÒ‰í—.ô¡nÿ°U » z z»\z0 ÉKVV ÷˜‚ $ˆƒ# 5z„# 8z…#  ;†# H‡# N”ˆ# ez‰#( n»Œ#0 vÈ#8 }èŽ#@ ƒ+#H ·F#P ¾”“#X ÂQ”#h Òz•#p ÖY˜#t Üe™#w ├#x æzŸ#ˆ ï  #qÿ¡¨ z6³z¸Î3 66Íßð4 z6Í606 z66(9G8 66JVW9 666gxt† 6666ˆžÁ‡VÙ… z6¹Åˆ6 zÕÕÚëJŠ8Û m}ä# }å# ‹}æ# —}ç# ¡}è#  ®}é#( ¸£ê#0 Í®ë#8 ã®ì#@ ï®í#H ûÊî#P ®ï#X }ð#` "}ñ#h ,}ò#p 3}ó#x :}ô#€ @ðõ#ˆ S®ö# Z®÷#˜ b®ø#  k®ù#¨ r®ú#° y}ü#¸ ˆ}ý#À œ}þ#È °}ÿ#ÐÂ}#Ø×£#àè}#èú}#ð }#ø}#€*}#ˆ8} #H} #˜W} # o} #¨†®#°ûm E6~Џ‰ 66Eš«Ô 66EE»ÑòŽ z6E6á÷‘ z6EE6"-’9N×P®#À}#ʰ#á°#éÖ# ü#( '#0B2#8Y}#@k°#H=}ã z666ô Å“!"#§}##´$#Ó%P '6amì:x5 )7» E6E–›±T±užE E6ÌÑâ”ŸÍ E6Eò÷ ² EV %`¤ λ¥# Ò6¦# ÖE§# ÚE¨# ãzª#  ìz«#$ ñͬ#( øÌ­#0 þÌ®#8 ̯#@  °#H »²#X) 0³æ z6ñ zö  :µ6ñ  ) Y¶0'C¶(#cÁ)#…ç*#¡ +#Á ,# H. -#(9 k.Ÿ z6»° Á •Ø z6Æ »Ñ ç ŸÙ 666z÷  Ä;Vê<V=x* F % \&# "6 '# 6z(# ?\*#A ]‹ 66»– § | z66»· Í ‡ š( sÍ # x¬  # ƒÒ # ŽÍ# ’»# Ý žÃ> Ý?  @ 6ÿEZ k  B 6ÿ66| ’ # A»£ « 3 1Ž › ˆD”EE#ËÿE#ÓEE#Û\F#èEG# õEG#(nK#0ÓL#8õM#@%N#H<>O#PO[P#X`yT#`ŸïU#h\V#pärZ#xõ£[#€ý[\#ˆ~]#Š^#˜6« a# y'd#¨‚\f#°‰ì j#¸¬Êm#Àµ q#ÈÐEt#Ðâ x#Øö* y#à† |#èR‘ }#ði1 ~#ø¦ÿ#€®6€#ˆ¶6 #ÐB ‚#˜êEƒ# øN „#¨ p …#° — †#¸+ ° ‡#À< ʈ#ÈE 6‰#ÐN 6Š#ØU 6‹#à^ 6Œ#èl 6#ðx nŽ#ø ¼ ‘#€à § j ”Ek# Ëÿk#¯ l+|6‰ _A F,PV¸ [ 0KÃ Ö ›Å }É LPVã ŸÁ pKø }_ ˜M 9Ý VÓ 9ÝPVÇ( ™ z# Y z# Ÿ Í# § z# : Í# N z# ² P - # 1 Í#È : Í#Ð B Í#Ø N z#à Y z#ä ` z #è d P!#ì j z"#ð p z##ô u Í$#ø z Í%#€  Í&#ˆ „ Í'# ‰ Í(#˜ Í)#  “ p*#¨{¸ + ”E# Ëÿ# % ›# Å Ò× @6 WVÓ @Ý#W“ BFò  W>V[>Ø 6| õ6>qVÓ õ6ŸÚ õ6èHqß ÷Ý  zqÅVÓ ÝAÚ 6wæ 6­}Å!: Í‘p!N z‘l!: Í‘p!: Í‘p!: Í‘p!: Í‘p!: Í‘p!N z‘l!N z‘l!N z‘l!N z‘l!N z‘l* z=VÓ W Ú 69æ 6o="~ 6‘P"ý 6‘H"œ "Í‘@"“ #z‘¼"ý 6‘H"ý 6‘H"ý 6‘H"ý 6‘H"ý 6‘H"œ "Í‘@"œ "Í‘@"œ "Í‘@"œ "Í‘@"œ "Í‘@"“ #z‘¼"“ #z‘¼"“ #z‘¼"“ #z‘¼"“ #z‘¼r zPó !z›Î  æûÖ 'H#À zÛ 6~à 6Úæ 6ýì æ $ö z$ÿ zš"~ 6‘P"~ 6‘P"~ 6‘P"~ 6‘P"~ 6‘PÔ÷"~ 6‘P÷*ç"~ 6‘P"~ 6‘P"~ 6‘P"~ 6‘P"~ 6‘P;æ"ý 6‘H}æŒÛ"ý 6‘H"ý 6‘H"ý 6‘H"ý 6‘H"ý 6‘H < ô6Ùª VÓ ô6k ~ ô6L ñª r ûzâ ì úæA Ö ø'¡ %À ÷zÛ ö6Ä à ö6 æ ö60 &ö ÷z&ÿ ÷z X ”6ÙVÓ ”W  Ú ”6H ™Ù! –z‘t È¼È! –z‘t! –z‘t! –z‘t! –z‘t! –z‘t l ¢6 ~VÓ ¢W Ú ¢6“´~! ªz‘T!e «6‘H ­z¶# ¬æÖ ¦'–%À ¥zÛ ¤6¹Æ ¨-Ü&ö ¥z¿eãe! ªz‘T! ªz‘T! ªz‘T! ªz‘T! ªz‘T!e «6‘H!e «6‘H!e «6‘H!e «6‘H!e «6‘H"Á!e «6‘HaÁl¶!e «6‘H!e «6‘H!e «6‘H!e «6‘H!e «6‘H  ä6= VÓ äW mÚ ä6£æ ä6ÆI !œ æÍ‘p!“ çz‘l_!œ æÍ‘p!œ æÍ‘p!œ æÍ‘p!œ æÍ‘p!œ æÍ‘p!“ çz‘l!“ çz‘l!“ çz‘l!“ çz‘l!“ çz‘l’ \6ïVÓ \W ,"» _6‘P"» _6‘P"» _6‘P"» _6‘P"» _6‘P"» _6‘P‰ azbÀ az…¢ az» _6Þ$Æ `-'¤ ¶ÅïVÓ ¶W ö(¹ -ª Ô VÓ -ÝS p  ’ ˜  Í#  Í# ¤#©$ Ûæ! H æ"# N Í## U z$#ð_ %"' r z(# ~ ë)#2‡ *U, - -# ó z.#È ý ë/#Ð , z0#Ø 6 z1#Ü A -2#à e `3#è “ z4#ð œ Í5#ø ¢ z6#€e¦ 7  ”EŽ# ËÿŽ# ë  # ® L %Rá $> I: ; I: ;&II' I  : ; I: ; 8 2  I' < $ > I!I/  : ;  I: ;8 2  : ; : ;4I: ;  4I: ; .: ; ' I? @ : ; I : ;  4: ; I.: ;' ? @ 4: ;I.: ;' I@ : ;I .: ; ' I@ !4: ; I "4: ;I #4: ;I $4: ;I%4: ; I &4: ; I'.: ;' @ (.: ; ' @ «Öû /System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7/usr/include._speedups.cobject.hstdio.hmethodobject.hdescrobject.hblock_locator.hscanner.h 9 K=] M ‘ZX m.Æò Mg“Krt‘Zæusu…sׄôru=PJ  ¡>Ë›|‚ ¾„''t ‘Z£.   ñ®ƒ!ue>!/ æ!! -ZxäCJò +§   Jƒv„3&­É./tKž gg.6ž­=5å‚.ƒ5ãƒó$‘%gÉ w<<¯Ÿ‘.,t= Ögå3Jf.3tYÉŸ‘a ä+ŸX¥Œä »ƒvuåöŸ³t  <­$­#.4t=¬ g­.;žƒ,É=‘ 7 ä’„•jÌ ù 0 ´ò ’u­½ŸØt {Éu.pä./žgž g­.6È×=5/‚.ƒ5ãƒó$Ÿ%­É w¬<„Ÿ›~ä ‘Z U U#P6QPÎ8S>OU\_UiqU>HTHi^\iSq}U}¾Sq—T—¬UqQ¬¾QÂÅQÅÎUÎèSïUð].KS:O^ãð^ƒžTµÜSAUA=vˆ[T[tULQtâQåGQJUQiwQ¦IQL˜Q¤ÈQÛÿQ.Q2=Q2ççç\û=2××ÛTÛêv°ê=‡Èv ÈÕQÕ=v ò^Xf^JiSmwS¦ÓS¤±P–£_³ç]ÀÓv¨ÓäSä=v¨=IUIS=tT=jQ†Q Q ´U´^Åv¸Å ^%^5e^ ÔT¹¶¶¶]Å~ã \0\3H\Jf\–¶\Åñ\5e\?f_‰žPÚñS5eS™U™ÈS±TÙ' U3 = UD G UO q Uv U§ ª Uµ ß U 3 Ud { U‰ Œ U‘ ª UÙíTí% ^3 L ^O ² ^µ Ü ^Ü d vPd t ^í\ \ ` ]` t vHt ª Q ‰ S0 H v¸H Y SY ª v¸[ ‰ _µ Ô SÜ æ S H S  ^" ` \ª ³ U³ Í Sp] q__sFILEÝ PyGetSetDef) bufferinfo_objectà _typeobjectA PyMethodDef”__sbufApple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)_speedups.c/usr/local/www/dubalu/libs/scss/srcPyExc_scss_NoMoreTokensob_refcntlong int__darwin_ssize_tssize_tPy_ssize_tob_typeob_sizetp_namechartp_basicsizetp_itemsizetp_deallocdestructortp_printint_punsigned char_r_w_flagsshort_file_bf_base_size__sbuf_lbfsize_cookie_close_read_seeklong long int__int64_t__darwin_off_tfpos_t_write_ub_extra__sFILEX_ur_ubuf_nbuf_lb_blksize_offset__sFILEFILEprintfunctp_getattrgetattrfunctp_setattrsetattrfunctp_comparecmpfunctp_reprreprfunctp_as_numbernb_addbinaryfuncnb_subtractnb_multiplynb_dividenb_remaindernb_divmodnb_powerternaryfuncnb_negativeunaryfuncnb_positivenb_absolutenb_nonzeroinquirynb_invertnb_lshiftnb_rshiftnb_andnb_xornb_ornb_coercecoercionnb_intnb_longnb_floatnb_octnb_hexnb_inplace_addnb_inplace_subtractnb_inplace_multiplynb_inplace_dividenb_inplace_remaindernb_inplace_powernb_inplace_lshiftnb_inplace_rshiftnb_inplace_andnb_inplace_xornb_inplace_ornb_floor_dividenb_true_dividenb_inplace_floor_dividenb_inplace_true_dividenb_indexPyNumberMethodstp_as_sequencesq_lengthlenfuncsq_concatsq_repeatssizeargfuncsq_itemsq_slicessizessizeargfuncsq_ass_itemssizeobjargprocsq_ass_slicessizessizeobjargprocsq_containsobjobjprocsq_inplace_concatsq_inplace_repeatPySequenceMethodstp_as_mappingmp_lengthmp_subscriptmp_ass_subscriptobjobjargprocPyMappingMethodstp_hashhashfunctp_calltp_strtp_getattrogetattrofunctp_setattrosetattrofunctp_as_bufferbf_getreadbufferreadbufferprocbf_getwritebufferwritebufferprocbf_getsegcountsegcountprocbf_getcharbuffercharbufferprocbf_getbufferbufobjlenitemsizereadonlyndimformatshapestridessuboffsetssmalltableinternalbufferinfoPy_buffergetbufferprocbf_releasebufferreleasebufferprocPyBufferProcstp_flagstp_doctp_traversevisitproctraverseproctp_cleartp_richcomparerichcmpfunctp_weaklistoffsettp_itergetiterfunctp_iternextiternextfunctp_methodsml_nameml_methPyCFunctionml_flagsml_docPyMethodDeftp_membersPyMemberDeftp_getsetnamegetgettersetsetterdocclosurePyGetSetDeftp_basetp_dicttp_descr_getdescrgetfunctp_descr_setdescrsetfunctp_dictoffsettp_initinitproctp_allocallocfunctp_newnewfunctp_freefreefunctp_is_gctp_basestp_mrotp_cachetp_subclassestp_weaklisttp_deltp_version_tagunsigned int_typeobject_objectPyObjectscss_methodsscss_ScannerTypePyTypeObjectscss_Scanner_methodsscss_BlockLocatorTypescss_BlockLocator_iterlocatorexc_codestrcodestrcodestr_ptrcodestr_szlinenoparinstrdepthskipthininitsafelosestartendblockerrorselpropselprop_szBlockBlockLocatorscss_BlockLocatorscss_BlockLocator_iternextinit_speedupsscss_locate_blocksscss_BlockLocator_initscss_Scanner_initscss_Scanner_setup_patternsscss_Scanner_rewindscss_Scanner_tokenscss_Scanner_resetscss_Scanner_reprscss_Scanner_deallocscss_BlockLocator_deallocselfmargsresultkwdsscannerignore_szignoretokexprpatternreal_pcrepcrePatterntokens_sztokens_bsztokensregexstringstring_szTokenrestrictionspatterns_szpatternsRestrictioninput_szinputposScannerscss_Scannerrepritmpp_token_ignoresizeitemitem0item1_patternsis_tuple_is_tupletoken_numrestrictions_sz_restrictions(ëëis#s#_speedups_BlockLocatorScanner_speedups.NoMoreTokensNoMoreTokenslocate_blocksLocate Scss blocks.s#scss.ScannerScanner object.OO|z#resetScan the next tokentokenGet the nth tokenrewindRewind scannersetup_patternsInitialize patterns.ii|Oiiss#|z# (@%d) %s = Nonescss._BlockLocatorInternal BlockLocator iterator object.HSAH   ÿÿÿÿþA¢Žª~&±lîN,JPCVÌØ91r„$*y+N±vtu‹Ò:DûkñEŸQñ›Ð©k]¿gU!#‰‡Ôäô$4DTdt„”¤´ÄÔäX S’ O< „ %Å ‰ø Á|;¹ cl ¸ g q* Ù Ó¤ 7× â Öã «ò 2HSAH ÿÿÿÿHSAH ÿÿÿÿHSAH'N  !$'),025ÿÿÿÿ67;=>BDÿÿÿÿÿÿÿÿEFÿÿÿÿGHÎå¯[íŸàõ*/‚鿇s‚«zDt/­î7ê(ÎÖÄ8ŸæÕ¬¨^B%㊰+€kÀäLgUïœÿ­ÕðZKÀ:Éãq«ü v´6—Ï’Öá~zÍ×™s.\C;²žÊ¨ þ0†¹PÁöý/.œ|¥MýqtÞFÔÍ“<²'É5ô˜Ò±&½-¶à‘J{H¡Hˆ.ê°¼êpüÒÀD¹hvÜ·^å܆…€IÊð5ÿp÷SðpìÉë{4ïwÎ’0€ˆ ì=, ÑÁ¯»‚ e3›´>¬Ôœ›üžŠ©œPŸ‡ÿÛ•Üsªÿ¤Œyq5îµ”˜](r°ìñ췇Š ‚A°óÊSØÜ÷\w°oæ ·¦Éc •|*­H—üˆ-þ"‰Æ¤7#«¥²„|áPÜG §Ëù4GZm€“¦¹Ìßò+>QdwаÃÖéü"5H[n”§ºÍàó,?Rex‹ž±Ä×êý#=Pcv‰œ¯ÂÕèû!4GZm€“¦¹ÌßòÝB ‡ UÃ6 ¦  0æ —ôT¶*6 ʸ9•Æ ê %) * N2B$m$ Û‰í$Á£÷q N ÓP§ ® L Ó°  ˜¯ + nŽ ¼ $òÖ0_ "t}~§.¸ p Ô°Å Ò‡Ò Ù®¡ÿ^”ÅkŸ  z$ž'$› à ² # — Ÿì FA P}ã-'|¬ ÀE: õìrY. )ŠG>Ö }šÝ 3 ° ü² pÄ ãP$W[JðuÁ¸ ÿ¨”ç'$  K>3!qT(ÑX=c ÞÑXÙÑÑXzRx $£ÿÿÿÿÿÿ A†C $Dô¢ÿÿÿÿÿÿKA†C $l£ÿÿÿÿÿÿçA†C Bƒ$”Ö£ÿÿÿÿÿÿ3A†C CƒŽ$¼á£ÿÿÿÿÿÿTA†C Eƒ$ä ¤ÿÿÿÿÿÿ*A†C Bƒ, ¤ÿÿÿÿÿÿ&A†C JƒŒŽ,<¥ÿÿÿÿÿÿ(A†C MƒŒŽ$lý§ÿÿÿÿÿÿcA†C Eƒ,”8¨ÿÿÿÿÿÿÞA†C MƒŒŽ$Äø©ÿÿÿÿÿÿIA†C Bƒ,ìªÿÿÿÿÿÿÑA†C MƒŒŽ$º«ÿÿÿÿÿÿ*A†C Bƒ½ >-” b= K-€ [-P O-4 O- I-þ I-÷ T-ç T-® I-¡ T-r L-H J-> U-* [-ò\-Ëb=Ä_-´B-£hb=_X-X-D-( F=E-H=ãK-Ó`-šO-…I-{T-WL-,J-%U-×B-Â’b=‹^-wB-b(K-K-]-µO- I-™T-sL-EJ->U-[-ÛO-ÄO-ŸI-I-ˆT-xT-CI-9T- L-ÞJ-×U-u\-aB-D R-ÄP-¹N-®S-ŸP-”Q-iP-^R-Y#R-ØZ-´A-B-ˆ e -Pa-K:M-, " C- M-üõîçM-ߨÑÇY-¸±ª[-¡?-‘W-Œ…~V=sW-ng`V=SX-K.D-&G=@-skH@‡d\·¯¦žyq91ÐÈ¿· ˜ûòê_W.&ÈÀ·¯˜g_ÉÁ˜,$ûó›“Š‚jb1)îæ'çß¹±†~WOD<÷ïëãÎ ¹ — u H än f [ S 8 0   ò ê ß × Ì Ä © ¡ „ | q i \ T I A %    þ ö ê â Ç ¿ ³ «   ˜  … z r g _ T L 1 )     ø ð å Ý Ò Ê ¿ · ¬ ¤ ™ ‘ † ~ s k P H - %   ÷ïäÜÁ¹ž–{sh`UMB:/' åÝÒʾ¶›“xpe]RJ=5*"ôìáÙÎÆ«£ˆ€umPH=5( ýâÚ¿·¬¤™‘†~c[PH+#ûß×Ê·¯£›wldXP5-"üôéáÖÎû°¨•Š‚woTLA9 æÞû ˜…jbG?4, þöÛÓÈÀµ­’Šw\TIA&ûðèÍź²§Ÿ„|aYNF+# H<@:,˜€+È"!8 ø ¸*¨ )˜(ˆ€'x&h`%X$H@# ÐTÐÌTÌÈTÈÄTÄÀTÀ¼T¼¸T¸´T´°T°¬T¬¨T¨¤T¤ T œTœ˜T˜”T”TŒTŒ0T0,T,(T($T$ T TTTT T TTTüTüøTøôTôðTðìTìèTèäTäàTàÜTÜØTØÔTÔÐTÐÌTÌÈTÈÄTÄÀTÀ¼T¼¸T¸´T´°T°¬T¬¨T¨¤T¤ T œTœ˜T˜”T”TŒTŒˆTˆ„T„€T€|T|xTxtTtpTplTlhThdTd`T`\T\XTXTTTPTPLTLHTHDTD@T@<T<8T84T40T0,T,(T($T$ T TTTT T TTTüTüàÀ €`@ ) O0 ˜MG LY &Oa 0Ko 0Ow >O FO‡ ]O _¨>¼qÔ ŒOÜÅòï .P /P 1P  BP)< ¬OE=Y *Pb v P $Pˆ P¦Ùê Þ jOæ xOî Oö œOÿ pK ²O ¸O' ÌO0 ÒO9 äOB ëOK úOT P] GPf ZPoÐ\y`]ˆ]«°]ÄØ]Ú^ð8^`^^6¸^Vè^W8]Ýè\ ø]˯58&a L|æBóï´"lƒW˜ØŽ¡pÜJÈÃ5N»m]_scss_BlockLocator_iter_scss_BlockLocator_iternext_BlockLocator_iternext_PyExc_StopIteration_PyErr_SetNone_Py_BuildValue_init_speedups_PyType_GenericNew_PyType_Ready_BlockLocator_initialize_Scanner_initialize_Py_InitModule4_64_PyModule_AddObject_PyErr_NewException__PyObject_New_PyArg_ParseTuple_BlockLocator_new_Scanner_del_PyString_FromString_PyString_ConcatAndDel_PyString_FromFormat_PyString_FromStringAndSize_PyObject_Repr_Scanner_initialized_PyTuple_Size_PyList_Size_PyMem_Malloc_PyTuple_GetItem_PyList_GetItem_PyString_AsString_Scanner_new_PyMem_Free_Scanner_reset__Py_NoneStruct_Scanner_token_PyExc_SyntaxError_PyErr_SetString_PyExc_NotImplementedError_Scanner_rewind_BlockLocator_del_scss_BlockLocator_iter.eh_scss_BlockLocator_iternext.eh_init_speedups.ehL_.str_scss_BlockLocatorType_scss_ScannerTypeL_.str1_scss_methodsL_.str2L_.str3L_.str4L_.str5_PyExc_scss_NoMoreTokens_scss_locate_blocks_scss_BlockLocator_initL_.str8_scss_Scanner_dealloc_scss_Scanner_reprL_.str24L_.str25L_.str26L_.str27_scss_Scanner_initL_.str11_scss_Scanner_resetL_.str23_scss_Scanner_tokenL_.str21L_.str22_scss_Scanner_rewindL_.str20_scss_Scanner_setup_patterns_scss_BlockLocator_deallocL_.str6L_.str7L_.str9L_.str10_scss_Scanner_methodsL_.str12L_.str13L_.str14L_.str15L_.str16L_.str17L_.str18L_.str19L_.str28L_.str29EH_frame0_scss_locate_blocks.eh_scss_BlockLocator_init.eh_scss_Scanner_dealloc.eh_scss_Scanner_repr.eh_scss_Scanner_init.eh_scss_Scanner_reset.eh_scss_Scanner_token.eh_scss_Scanner_rewind.eh_scss_Scanner_setup_patterns.eh_scss_BlockLocator_dealloc.ehpyScss-1.1.5/scss/src/block_locator.c0000644000076500000240000003416111713616175020215 0ustar kronuzstaff00000000000000/* * pyScss, a Scss compiler for Python * SCSS blocks scanner. * * German M. Bravo (Kronuz) * https://github.com/Kronuz/pyScss * * MIT license (http://www.opensource.org/licenses/mit-license.php) * Copyright (c) 2011 German M. Bravo (Kronuz), All rights reserved. */ #include #include #include #include #include "block_locator.h" int _strip(char *begin, char *end, int *lineno) { // " 1\0 some, \n 2\0 aca " int _cnt, cnt = 0, pass = 1, addnl = 0; char c, *line = NULL, *first = begin, *last = begin, *write = lineno ? begin : NULL; while (begin < end) { c = *begin; if (c == '\0') { if (lineno && line == NULL) { line = first - 1; do { c = *++line; } while (c == ' ' || c == '\t' || c == '\n' || c == ';'); if (c != '\0') { sscanf(line, "%d", lineno); } } first = last = begin + 1; pass = 1; } else if (c == '\n') { _cnt = (int)(last - first); if (_cnt > 0) { cnt += _cnt + addnl; if (write != NULL) { if (addnl) { *write++ = '\n'; } while (first < last) { *write++ = *first++; } addnl = 1; } } first = last = begin + 1; pass = 1; } else if (c == ' ' || c == '\t') { if (pass) { first = last = begin + 1; } } else { last = begin + 1; pass = 0; } begin++; } _cnt = (int)(last - first); if (_cnt > 0) { cnt += _cnt + addnl; if (write != NULL) { if (addnl) { *write++ = '\n'; } while (first < last) { *write++ = *first++; } } } return cnt; } /* BlockLocator */ typedef void _BlockLocator_Callback(BlockLocator*); static void _BlockLocator_start_string(BlockLocator *self) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif // A string starts self->instr = *(self->codestr_ptr); } static void _BlockLocator_end_string(BlockLocator *self) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif // A string ends (FIXME: needs to accept escaped characters) self->instr = 0; } static void _BlockLocator_start_parenthesis(BlockLocator *self) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif // parenthesis begins: self->par++; self->thin = NULL; self->safe = self->codestr_ptr + 1; } static void _BlockLocator_end_parenthesis(BlockLocator *self) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif self->par--; } static void _BlockLocator_flush_properties(BlockLocator *self) { int len, lineno = -1; #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif // Flush properties if (self->lose <= self->init) { len = _strip(self->lose, self->init, &lineno); if (len) { if (lineno != -1) { self->lineno = lineno; } self->block.selprop = self->lose; self->block.selprop_sz = len; self->block.codestr = NULL; self->block.codestr_sz = 0; self->block.lineno = self->lineno; self->block.error = 1; } self->lose = self->init; } } static void _BlockLocator_start_block1(BlockLocator *self) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif // Start block: if (self->codestr_ptr > self->codestr && *(self->codestr_ptr - 1) == '#') { self->skip = 1; } else { self->start = self->codestr_ptr; if (self->thin != NULL && _strip(self->thin, self->codestr_ptr, NULL)) { self->init = self->thin; } _BlockLocator_flush_properties(self); self->thin = NULL; } self->depth++; } static void _BlockLocator_start_block(BlockLocator *self) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif // Start block: self->depth++; } static void _BlockLocator_end_block1(BlockLocator *self) { int len, lineno = -1; #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif // Block ends: self->depth--; if (!self->skip) { self->end = self->codestr_ptr; len = _strip(self->init, self->start, &lineno); if (lineno != -1) { self->lineno = lineno; } self->block.selprop = self->init; self->block.selprop_sz = len; self->block.codestr = (self->start + 1); self->block.codestr_sz = (int)(self->end - (self->start + 1)); self->block.lineno = self->lineno; self->block.error = 1; self->init = self->safe = self->lose = self->end + 1; self->thin = NULL; } self->skip = 0; } static void _BlockLocator_end_block(BlockLocator *self) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif // Block ends: self->depth--; } static void _BlockLocator_end_property(BlockLocator *self) { int len, lineno = -1; #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif // End of property (or block): self->init = self->codestr_ptr; if (self->lose <= self->init) { len = _strip(self->lose, self->init, &lineno); if (len) { if (lineno != -1) { self->lineno = lineno; } self->block.selprop = self->lose; self->block.selprop_sz = len; self->block.codestr = NULL; self->block.codestr_sz = 0; self->block.lineno = self->lineno; self->block.error = 1; } self->init = self->safe = self->lose = self->codestr_ptr + 1; } self->thin = NULL; } static void _BlockLocator_mark_safe(BlockLocator *self) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif // We are on a safe zone if (self->thin != NULL && _strip(self->thin, self->codestr_ptr, NULL)) { self->init = self->thin; } self->thin = NULL; self->safe = self->codestr_ptr + 1; } static void _BlockLocator_mark_thin(BlockLocator *self) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif // Step on thin ice, if it breaks, it breaks here if (self->thin != NULL && _strip(self->thin, self->codestr_ptr, NULL)) { self->init = self->thin; self->thin = self->codestr_ptr + 1; } else if (self->thin == NULL && _strip(self->safe, self->codestr_ptr, NULL)) { self->thin = self->codestr_ptr + 1; } } int function_map_initialized = 0; _BlockLocator_Callback* scss_function_map[256 * 256 * 2 * 3]; // (c, instr, par, depth) static void init_function_map(void) { int i; #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif if (function_map_initialized) { return; } function_map_initialized = 1; for (i = 0; i < 256 * 256 * 2 * 3; i++) { scss_function_map[i] = NULL; } scss_function_map[(int)'\"' + 256*0 + 256*256*0 + 256*256*2*0] = _BlockLocator_start_string; scss_function_map[(int)'\'' + 256*0 + 256*256*0 + 256*256*2*0] = _BlockLocator_start_string; scss_function_map[(int)'\"' + 256*0 + 256*256*1 + 256*256*2*0] = _BlockLocator_start_string; scss_function_map[(int)'\'' + 256*0 + 256*256*1 + 256*256*2*0] = _BlockLocator_start_string; scss_function_map[(int)'\"' + 256*0 + 256*256*0 + 256*256*2*1] = _BlockLocator_start_string; scss_function_map[(int)'\'' + 256*0 + 256*256*0 + 256*256*2*1] = _BlockLocator_start_string; scss_function_map[(int)'\"' + 256*0 + 256*256*1 + 256*256*2*1] = _BlockLocator_start_string; scss_function_map[(int)'\'' + 256*0 + 256*256*1 + 256*256*2*1] = _BlockLocator_start_string; scss_function_map[(int)'\"' + 256*0 + 256*256*0 + 256*256*2*2] = _BlockLocator_start_string; scss_function_map[(int)'\'' + 256*0 + 256*256*0 + 256*256*2*2] = _BlockLocator_start_string; scss_function_map[(int)'\"' + 256*0 + 256*256*1 + 256*256*2*2] = _BlockLocator_start_string; scss_function_map[(int)'\'' + 256*0 + 256*256*1 + 256*256*2*2] = _BlockLocator_start_string; scss_function_map[(int)'\"' + 256*(int)'\"' + 256*256*0 + 256*256*2*0] = _BlockLocator_end_string; scss_function_map[(int)'\'' + 256*(int)'\'' + 256*256*0 + 256*256*2*0] = _BlockLocator_end_string; scss_function_map[(int)'\"' + 256*(int)'\"' + 256*256*1 + 256*256*2*0] = _BlockLocator_end_string; scss_function_map[(int)'\'' + 256*(int)'\'' + 256*256*1 + 256*256*2*0] = _BlockLocator_end_string; scss_function_map[(int)'\"' + 256*(int)'\"' + 256*256*0 + 256*256*2*1] = _BlockLocator_end_string; scss_function_map[(int)'\'' + 256*(int)'\'' + 256*256*0 + 256*256*2*1] = _BlockLocator_end_string; scss_function_map[(int)'\"' + 256*(int)'\"' + 256*256*1 + 256*256*2*1] = _BlockLocator_end_string; scss_function_map[(int)'\'' + 256*(int)'\'' + 256*256*1 + 256*256*2*1] = _BlockLocator_end_string; scss_function_map[(int)'\"' + 256*(int)'\"' + 256*256*0 + 256*256*2*2] = _BlockLocator_end_string; scss_function_map[(int)'\'' + 256*(int)'\'' + 256*256*0 + 256*256*2*2] = _BlockLocator_end_string; scss_function_map[(int)'\"' + 256*(int)'\"' + 256*256*1 + 256*256*2*2] = _BlockLocator_end_string; scss_function_map[(int)'\'' + 256*(int)'\'' + 256*256*1 + 256*256*2*2] = _BlockLocator_end_string; scss_function_map[(int)'(' + 256*0 + 256*256*0 + 256*256*2*0] = _BlockLocator_start_parenthesis; scss_function_map[(int)'(' + 256*0 + 256*256*1 + 256*256*2*0] = _BlockLocator_start_parenthesis; scss_function_map[(int)'(' + 256*0 + 256*256*0 + 256*256*2*1] = _BlockLocator_start_parenthesis; scss_function_map[(int)'(' + 256*0 + 256*256*1 + 256*256*2*1] = _BlockLocator_start_parenthesis; scss_function_map[(int)'(' + 256*0 + 256*256*0 + 256*256*2*2] = _BlockLocator_start_parenthesis; scss_function_map[(int)'(' + 256*0 + 256*256*1 + 256*256*2*2] = _BlockLocator_start_parenthesis; scss_function_map[(int)')' + 256*0 + 256*256*1 + 256*256*2*0] = _BlockLocator_end_parenthesis; scss_function_map[(int)')' + 256*0 + 256*256*1 + 256*256*2*1] = _BlockLocator_end_parenthesis; scss_function_map[(int)')' + 256*0 + 256*256*1 + 256*256*2*2] = _BlockLocator_end_parenthesis; scss_function_map[(int)'{' + 256*0 + 256*256*0 + 256*256*2*0] = _BlockLocator_start_block1; scss_function_map[(int)'{' + 256*0 + 256*256*0 + 256*256*2*1] = _BlockLocator_start_block; scss_function_map[(int)'{' + 256*0 + 256*256*0 + 256*256*2*2] = _BlockLocator_start_block; scss_function_map[(int)'}' + 256*0 + 256*256*0 + 256*256*2*1] = _BlockLocator_end_block1; scss_function_map[(int)'}' + 256*0 + 256*256*0 + 256*256*2*2] = _BlockLocator_end_block; scss_function_map[(int)';' + 256*0 + 256*256*0 + 256*256*2*0] = _BlockLocator_end_property; scss_function_map[(int)',' + 256*0 + 256*256*0 + 256*256*2*0] = _BlockLocator_mark_safe; scss_function_map[(int)'\n' + 256*0 + 256*256*0 + 256*256*2*0] = _BlockLocator_mark_thin; scss_function_map[0 + 256*0 + 256*256*0 + 256*256*2*0] = _BlockLocator_flush_properties; scss_function_map[0 + 256*0 + 256*256*0 + 256*256*2*1] = _BlockLocator_flush_properties; scss_function_map[0 + 256*0 + 256*256*0 + 256*256*2*2] = _BlockLocator_flush_properties; #ifdef DEBUG fprintf(stderr, "\tScss function maps initialized!\n"); #endif } /* BlockLocator public interface */ void BlockLocator_initialize(void) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif init_function_map(); } void BlockLocator_finalize(void) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif } BlockLocator * BlockLocator_new(char *codestr, int codestr_sz) { BlockLocator *self; #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif self = PyMem_New(BlockLocator, 1); if (self) { memset(self, 0, sizeof(BlockLocator)); self->_codestr = PyMem_New(char, codestr_sz); memcpy(self->_codestr, codestr, codestr_sz); self->codestr_sz = codestr_sz; self->codestr = PyMem_New(char, self->codestr_sz); memcpy(self->codestr, self->_codestr, self->codestr_sz); self->codestr_ptr = self->codestr; self->lineno = 0; self->par = 0; self->instr = 0; self->depth = 0; self->skip = 0; self->thin = self->codestr; self->init = self->codestr; self->safe = self->codestr; self->lose = self->codestr; self->start = NULL; self->end = NULL; #ifdef DEBUG fprintf(stderr, "\tScss BlockLocator object created (%d bytes)!\n", codestr_sz); #endif } return self; } void BlockLocator_del(BlockLocator *self) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif free(self->codestr); free(self->_codestr); free(self); } void BlockLocator_rewind(BlockLocator *self) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif free(self->codestr); self->codestr = PyMem_New(char, self->codestr_sz); memcpy(self->codestr, self->_codestr, self->codestr_sz); self->codestr_ptr = self->codestr; self->lineno = 0; self->par = 0; self->instr = 0; self->depth = 0; self->skip = 0; self->thin = self->codestr; self->init = self->codestr; self->safe = self->codestr; self->lose = self->codestr; self->start = NULL; self->end = NULL; #ifdef DEBUG fprintf(stderr, "\tScss BlockLocator object rewound!\n"); #endif } Block* BlockLocator_iternext(BlockLocator *self) { _BlockLocator_Callback *fn; char c = 0; char *codestr_end = self->codestr + self->codestr_sz; #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif memset(&self->block, 0, sizeof(Block)); while (self->codestr_ptr < codestr_end) { c = *(self->codestr_ptr); if (!c) { self->codestr_ptr++; continue; } repeat: fn = scss_function_map[ (int)c + 256 * self->instr + 256 * 256 * (int)(self->par != 0) + 256 * 256 * 2 * (int)(self->depth > 1 ? 2 : self->depth) ]; if (fn != NULL) { fn(self); } self->codestr_ptr++; if (self->codestr_ptr > codestr_end) { self->codestr_ptr = codestr_end; } if (self->block.error) { #ifdef DEBUG if (self->block.error > 0) { fprintf(stderr, "\tBlock found!\n"); } else { fprintf(stderr, "\tException!\n"); } #endif return &self->block; } } if (self->par > 0) { if (self->block.error >= 0) { self->block.error = -1; sprintf(self->exc, "Missing closing parenthesis somewhere in block"); #ifdef DEBUG fprintf(stderr, "\t%s\n", self->exc); #endif } } else if (self->instr != 0) { if (self->block.error >= 0) { self->block.error = -2; sprintf(self->exc, "Missing closing string somewhere in block"); #ifdef DEBUG fprintf(stderr, "\t%s\n", self->exc); #endif } } else if (self->depth > 0) { if (self->block.error >= 0) { self->block.error = -3; sprintf(self->exc, "Missing closing string somewhere in block"); #ifdef DEBUG fprintf(stderr, "\t%s\n", self->exc); #endif } if (self->init < codestr_end) { c = '}'; goto repeat; } } if (self->init < codestr_end) { self->init = codestr_end; c = 0; goto repeat; } BlockLocator_rewind(self); return &self->block; } pyScss-1.1.5/scss/src/block_locator.h0000644000076500000240000000205611676202063020213 0ustar kronuzstaff00000000000000/* * pyScss, a Scss compiler for Python * SCSS blocks scanner. * * German M. Bravo (Kronuz) * https://github.com/Kronuz/pyScss * * MIT license (http://www.opensource.org/licenses/mit-license.php) * Copyright (c) 2011 German M. Bravo (Kronuz), All rights reserved. */ #ifndef BLOCK_LOCATOR_H #define BLOCK_LOCATOR_H #define MAX_EXC_STRING 200 typedef struct { int error; int lineno; char *selprop; int selprop_sz; char *codestr; int codestr_sz; } Block; typedef struct { char exc[MAX_EXC_STRING]; char *_codestr; char *codestr; char *codestr_ptr; int codestr_sz; int lineno; int par; char instr; int depth; int skip; char *thin; char *init; char *safe; char *lose; char *start; char *end; Block block; } BlockLocator; void BlockLocator_initialize(void); void BlockLocator_finalize(void); Block* BlockLocator_iternext(BlockLocator *self); BlockLocator *BlockLocator_new(char *codestr, int codestr_sz); void BlockLocator_del(BlockLocator *self); #endif pyScss-1.1.5/scss/src/block_locator.o0000644000076500000240000011537012034740572020227 0ustar kronuzstaff00000000000000Êþº¾=Ð PJø Îúíþ¬ DÐ&ÈÌ&__text__TEXT‘ È”,—€__debug_info__DWARF‘ …YL1P__debug_abbrev__DWARF2Þ__debug_aranges__DWARFH__debug_macinfo__DWARFH__debug_line__DWARFHdÌ3__debug_loc__DWARF¬OtÔ3v__debug_pubtypes__DWARFûÃ!__debug_str__DWARF îÕ!__debug_ranges__DWARFûÃ%__data__DATAûÃ%__cstring__TEXTû\Ã%__common__DATAÌ&__apple_names__DWARFW œ&„70__apple_objc__DWARFó"$»(__apple_namespac__DWARF#$ß(__apple_types__DWARF;# )9__debug_inlined__DWARF[$R#*„9__debug_frame__DWARF°$x*´9L:;@ P U‰åSWVƒì,èX‹u1Ƀ}¿Eþ;u rÇEä‰ð1Ûé ÇEì€í‰Eà‰ð‰ò1Û‰MèÇEä‰UðŠ €ù¯„Ét,€ù „§€ù …°‰Á)ñ…É~V‹UäÚʉUä…ÿuY1ÿëDƒ}t>ƒ}èu8ë<;uFŠ<:õ„Àt$ˆÁ€Á÷€ùrë< tç‹E‰D$‹Eà‰D$‰4$è,ÿÿÿ‰uè‹UðrÇEì‰ðëN…ÛtÆ G»9ÆsÞ‰ù)ñÈŠˆFG»9øuñ‰ÇëÅ€ù u‹UðJƒ}ìEÁEñë ‹UðBÇEìB;U …ÿÿÿ‰Á)ñ…É‹Eäë)‹UäÚÊ…ÿt…ÛtÆ G9Æs‰ù)ñÈŠˆFG9øuö‰ÐƒÄ,^_[]ÃU‰åVƒìè^¾B%…pdžB%†F%‰$ÇD$èEþÿÿ†%‰†Î%‰†â%‰†Î%‰†â%‰†Î%‰†â%‰†Î% ‰†â% ‰†Î%‰†â%‰†Î%‰†â%†;‰†Î­‰†âÁ‰†Î­‰†âÁ‰†Î­‰†âÁ‰†Î­ ‰†âÁ ‰†Î­‰†âÁ‰†Î­‰†âÁ†J‰†æ%‰†æ%‰†æ%‰†æ% ‰†æ%‰†æ%†o‰†ê%‰†ê% ‰†ê%†}‰†2'†ù‰†2'‰†2'†‰†:'†Ú‰†:'†è‰†2&†›‰†ö%†ö‰†n%†q‰†F%‰†F%‰†F%ƒÄ^]ÃU‰å]ÃU‰åSWVƒì Ç$èÕüÿÿ‰Æ…ö„׋} ‹]‰4$ÇD$èµüÿÿ1À…ÿx‰<$è§üÿÿ‰†È‰|$‰\$‰$è‘üÿÿ‰¾Ô1À…ÿx‰<$è}üÿÿ‹¾Ô‰†Ì‹ŽÈ‰|$‰L$‰$è[üÿÿ‹†Ì‰†ÐdžØÇ†ÜƆàdžädž艆쉆ð‰†ô‰†øÇ†üdž‰ðƒÄ ^_[]ÃU‰åVP‹u‹†Ì‰$èÔûÿÿ‹†È‰$èÆûÿÿƒÄ^]é¼ûÿÿU‰åVƒì‹u‹†Ì‰$è¤ûÿÿ‹ŽÔ…Éy1Àë‰ $èŽûÿÿ‹ŽÔ‰†Ì‹–ȉL$‰T$‰$èlûÿÿ‹†Ì‰†ÐdžØÇ†ÜƆàdžädž艆쉆ð‰†ô‰†øÇ†üdžƒÄ^]ÃU‰åSWVƒìèY‹}‹ŸÌŸÔ·ÇFÇÇF ÇFÇFÇF‹‡Ð‰Mì‘ï‰U艉Mðëp‰Ÿð1É‹‡ä‰ÂÁâƒø¸Oо‡àÁàÈЃ¿Ü•Á¶ÉÁáÁ‹Eì‹„ˆÁ!…Àt‰<$ÿЋ‡Ð@9ØGɇЃ¿…Ê9Øs¾…Éu@‰‡Ðë샿Ü~4ƒ>ˆÇ‡ÿÿÿÿ‹Eè‰D$ ‰<$ÇD$ÿÿÿÿÇD$èÖùÿÿëe€¿àtƒ>xWLJþÿÿÿ‹EðëŃ¿ä~?ƒ>x)LJýÿÿÿ‹Eð‰D$ ‰<$ÇD$ÿÿÿÿÇD$è€ùÿÿ¹}9Ÿð‚âþÿÿ9Ÿð‚Îþÿÿ‰<$èŸýÿÿ‰ðƒÄ^_[]ÃU‰å‹E‹ˆÐŠ ˆˆà]ÃU‰å‹EÆ€à]ÃU‰å‹Eÿ€Üǀ싈ÐA‰ˆô]ÃU‰å‹EÿˆÜ]ÃU‰åVƒì‹u‹†Ð;†Ìv€xÿ#u džèëF‰†ü‹Žì…Ét$‰D$‰ $ÇD$è«øÿÿ…Àt ‹†ì‰†ð‰4$èŽdžìÿ†äƒÄ^]ÃU‰å‹Eÿ€ä]ÃU‰åWVƒìÇEôÿÿÿÿ‹uÿŽäƒ¾è…‹†Ð‰†‹†ð‹ŽüUô‰T$‰L$‰$èøÿÿ‹Môƒùÿu‹ŽØë‰ŽØ‹–ð‰– ‰†‹–üB‰–‹†‰Ç)׉¾‰Ždž@‰†ø‰†ô‰†ðdžìdžèƒÄ^_]ÃU‰å‹Eÿˆä]ÃU‰åVƒìÇEøÿÿÿÿ‹u‹†Ð‰†ð‹Žø9Áw|Uø‰T$‰D$‰ $èT÷ÿÿ…ÀtL‹Møƒùÿu‹ŽØë‰ŽØ‹–ø‰– ‰†dždž‰Ždž‹†Ð@‰†ø‰†ô‰†ðdžìƒÄ^]ÃU‰åVƒì‹u‹†ì…Àt*‹ŽÐ‰L$‰$ÇD$è­öÿÿ…Àt ‹†ì‰†ðdž싆Ð@‰†ôƒÄ^]ÃU‰åVƒì‹u‹†ì…Àt0‹ŽÐ‰L$‰$ÇD$èRöÿÿ‹Žì…Àt‰Žðë(…Éu1‹ŽÐ‹†ô‰L$‰$ÇD$èöÿÿ…Àt ‹†Ð@‰†ìƒÄ^]ÃU‰åVƒìÇEøÿÿÿÿ‹u‹†ð‹Žø9ÁwoUø‰T$‰D$‰ $èÑõÿÿ…ÀtL‹Møƒùÿu‹ŽØë‰ŽØ‹–ø‰– ‰†dždž‰Ždž‹†ð‰†øƒÄ^]à L\™€#Ì&³=DÇ= ## à## &S# .##  ÁS# Õ## X9  ¯G# ¸S#È ÁS#Ì ÉS#Ð Õ##Ô à##Ø ç# #Ü ë=!#à ñ#"#ä ÷###è üS$#ì S%#ð S&#ô S'#ø S(#ü S)#€ ·*#„ Â?+×  â çLWïúDÿÿÿÐ&c#~U`SSà\~f#l#q#uSbzS·€SK…S–‹=à#þjo~U& u>‚yU˜âUÁS/Õ#Öƒâ; ì;M‹ù¼_o¼•¥©¥DU֥⑺±DUÖ±âBN¼„”¹ÎÍ·¯UÖÍâU¯‹Ð= ÛÑSs çÏú‘ì%N×!”Q#·"ä;ëš;ëÐ;¡;s#"øQë”Q#šQë”Q#¡Qs$ !%’"#%’"#&ƒû ‘ UÖƒâ)þ ‘ 'à„#‘xê„#< ‹ 3  'à„#‘x'à„#‘x'à„#‘x'à„#‘x'à„#‘x(=€ û UÖâ(U% € UÖâ&mär% UÖäâÝu% 'àå#‘xêå#𜠰ü'àå#‘x'àå#‘x'àå#‘x'àå#‘x'àå#‘x&ˆÚdrU)ÖÚâ‘& ¼‘dUּⷔd'à½#‘tê½#ʶS'à½#‘t'à½#‘t'à½#‘t'à½#‘t'à½#‘t&¹²ƒ‘U)Ö²â‘&ÓžƒUÖžâ¤&îzùU)Özâ‘& nÔùU)Önâ‘&,dÅÔU)Ödâ‘&EZ¯ÅU)ÖZâ‘#§ a¹Z hÉN*~%Rá $> 4I? : ; $ > I!I/ I : ; I: ; 8 2 I: ;  : ; ' I!I/.: ; ' I? @ : ; I: ; I 4: ; I 4: ; I.: ;' ? @ 1X Y41 .: ;' ? @ .: ;' I? @ : ;I4: ;I1 1X Y: ;I 4: ;I 4: ;I!: ; I ".: ; ' I #$.: ;' % &.: ; ' @ '4: ; I (.: ;' @ ): ; I *&`\û ./usr/include/secureblock_locator.cblock_locator.h_string.h!  º Öx‚ƒ ¬®utžKh…ÝK’Ÿ« ò;è¡ ôKKKLŸekŸ‚ ¸<“¡Z»ggggggggggh»ggggggggggh»ggggh»gh»»h»¼¼¼¼»gfj @2  C8Ê}"¹ J8±}ÖÑò»ƒeg8­}fÔò»ŸŸuŸŸggggŸ££ ‡××£ £×Öƒeg8„}fýò»ŸŸuŸŸggggŸ£j6 #À8ü|f†)'f ÖG‚D[‘;kgÈLu!‘‘Ÿ ÷‘YŸ ]‘YŸ$¿À…·|ž l×1 lu1 lgŸÉ1 kg. ¤=¼gžu¼ƒ gi lg1 =ëgÉ »׊y‚i»gÉóg / Ÿw lg1 =Ý» É>Šy‚i»gŸŸg „Ÿi ¤žÉ¼ŸÉi ¤ž “cK „#J$Êè~f =Ý />Šy‚i»gŸŸg ¼~ˆˆ‹R‹udTTdRy~%V5IVIURUUVÝæVæèP/6P%V5IVIURUUVÝæVæèPVotVIVIURUUV7@R%Q5UQUPudPRRXdRy~P %W5UWððWW``WptWZcQ¨¬P}QDHQ‰W{SDÿVW,¥WS,S³¼PV‘aVáPr# V¬üP% ~ V€ õ Vû ‹ V/  P…Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)block_locator.c/usr/local/www/dubalu/libs/scss/srcfunction_map_initializedintscss_function_mapexcchar_codestrcodestrcodestr_ptrcodestr_szlinenoparinstrdepthskipthininitsafelosestartendblockerrorselpropselprop_szBlockBlockLocator_BlockLocator_Callback_stripBlockLocator_initializeBlockLocator_finalizeBlockLocator_newBlockLocator_delBlockLocator_rewindBlockLocator_iternext__inline_memcpy_chk__inline_memset_chkinit_function_map_BlockLocator_flush_properties_BlockLocator_mark_thin_BlockLocator_mark_safe_BlockLocator_end_property_BlockLocator_end_block_BlockLocator_end_block1_BlockLocator_start_block_BlockLocator_start_block1_BlockLocator_end_parenthesis_BlockLocator_start_parenthesis_BlockLocator_end_string_BlockLocator_start_stringbeginaddnlpasscntlastfirstlinewritec_cnti__val__dest__lenlong unsigned int__darwin_size_tsize_t__srcselfcodestr_endfnlen%dMissing closing parenthesis somewhere in blockMissing closing string somewhere in blockHSAH  ÿÿÿÿ ÿÿÿÿðö”ïïx8´sá;.Ù«ñ€ %*9¬Û† c´s•ÓÙ+M ÇÎÎŽ¦'»1V©Ûív×í´>Û·.«‚1µ]¯úpµ“:ª «S4¡›–z?þ4¡ãÙ>{ 0@Xhxˆ˜¨¸ÌÜìü ,<L\l|ŒM ü©Ò䯿#Ó¶,ºö˜>jðm8ø””E;c!Î5îØˆÛ‚*€* ù¹•U  =ðHSAH ÿÿÿÿHSAH ÿÿÿÿHSAH ÿÿÿÿÿÿÿÿÿÿÿÿ0€ˆ °oæ “òÐc •|¤7#«µà&ï½|5û/“ûyˆ›®ÁÔçú ™#$9·És³=$?×¹h§a$LïN   øø”;”%ää¯_¿•#„ÿÿÿÿ| ˆ~A„B F†‡ƒ~“A„B D†A„B A„B F†‡ƒ.A„B B†D½A„B D†®A„B F†‡ƒ¯A„B ÅA„B Ô%A„B ùA„B |A„B D†ƒA„B ‘ÓA„B E†‡dA„B r³A„B D†% [A„B D†€ {A„B D†û –A„B D†+ à ª O ¨ÝiQ¡| & ¯¢Ð&¡b¤- ¡Y¤þ¡ n X @ 6 ( ¡  k U G ' ¢Ð&¡Š¢Ð&¡Šû¢Ð&¡Šõ¤û ¡Šï¢Ð&¡Šé¤€ ¡Šã¢Ð&¡ŠÝ¤% ¡Š×¢Ð&¡ŠÑ¤r¡ŠË¢Ð&¡ŠÅ¤d¡Š¿¢Ð&¡Š¹¤‘¡Š³¢Ð&¡Š­¢Ð&¡Š§¤ƒ¡Š¡¢Ð&¡Š›¤¡Š•¢Ð&¡Š¢Ð&¡Š‰¢Ð&¡Šƒ¤ù¡Š}¢Ð&¡Šw¢Ð&¡Šq¢Ð&¡Šk¢Ð&¡Še¢Ð&¡Š_¢Ð&¡ŠY¤Ô¡ŠS¢Ð&¡ŠM¢Ð&¡ŠG¢Ð&¡ŠA¢Ð&¡Š;¢Ð&¡Š5¢Ð&¡Š/¢Ð&¡Š)¢Ð&¡Š#¢Ð&¡Š¢Ð&¡Š¢Ð&¡Š¢Ð&¡Š ¤Å¡Š¢Ð&¡Šÿ¢Ð&¡Šù¢Ð&¡Šó¢Ð&¡Ší¢Ð&¡Šç¢Ð&¡Šá¢Ð&¡ŠÛ¢Ð&¡ŠÕ¢Ð&¡ŠÏ¢Ð&¡ŠÉ¢Ð&¡ŠÃ¢Ð&¡Š½¤¯¡Š· §¢Ð&¡Š¢Ì&¡Š¢Ì&¡ŠÐ >¤û¡GC&"äྡHD"ç㉄€^ZD@!ýù¢ž™•soYU™b^GC,(àÜÈĸ´™Œ{wPL84 þúb^2. 9 j@<-)ôðáÝÎÊ»·¨¤•‘‚~wsd`YUFB3/   þïëäàÑÍÆÂ»·°¬¥¡š–‡ƒ|xqmeaZVOK<81-&"ýùòîçãÜØÑÍÆÂ»·¨¤™’އƒ|xqmfbRNGC;7/+$  ¤ã"¡W ¤Ó"¡W ¤Ã"¡W ¤³"¡W ü¤£"¡W ø¤“"¡W ô¤ƒ"¡W ð¤s"¡W ì¤c"¡W è¤S"¡W ä¤C"¡W à¤3"¡W ܤ#"¡W ؤ"¡W Ô¤ÿ!¡W Фï!¡W ̤ß!¡W ȤÏ!¡W Ĥ¿!¡W À¤¯!¡W ¼¤—!¡W ¸¤‡!¡W ´¤w!¡W °¤g!¡W „¤H$¡;#€¤5$¡;#|¤"$¡;#x¤$¡;#t¤ü#¡;#p¤é#¡;#l¤Ö#¡;#h¤Ã#¡;#NF>-%ìдœ|dH0èȬpX<ò¯Å(ÔIùh„ƒŸ‘¹dÒrî% € û Ÿ`~Ìw·D* Ì&D Ð&‰Wã±— __strip_sscanf_BlockLocator_initialize_function_map_initialized_scss_function_map___bzero_BlockLocator_finalize_BlockLocator_new_PyMem_Malloc_memcpy_BlockLocator_del_free_BlockLocator_rewind_BlockLocator_iternext___sprintf_chk__BlockLocator_start_string__BlockLocator_end_string__BlockLocator_start_parenthesis__BlockLocator_end_parenthesis__BlockLocator_start_block1__BlockLocator_start_block__BlockLocator_end_block1__BlockLocator_end_block__BlockLocator_end_property__BlockLocator_mark_safe__BlockLocator_mark_thin__BlockLocator_flush_propertiesÏúíþð ˆ/0€/__text__TEXTÑ 6X€__debug_info__DWARFÑ Ø áP9P__debug_abbrev__DWARF©¹__debug_aranges__DWARF½Í__debug_macinfo__DWARF½Í__debug_line__DWARF½rÍÐ;__debug_loc__DWARF/?!Ø;¢__debug_pubtypes__DWARFJ"Z)__debug_str__DWARF\"îl)__debug_ranges__DWARFJ&Z-__data__DATAJ&Z-__cstring__TEXTJ&\Z-__common__DATA€/0__apple_names__DWARF¦&œ¶-è@0__apple_objc__DWARFB)$R0__apple_namespac__DWARFf)$v0__apple_types__DWARFŠ) š0hB__debug_inlined__DWARFª*jº1èB__compact_unwind__LD+@$2C __eh_frame__TEXTX,(h3 hhC2ˆFp P,UH‰åAWAVAUATSHƒìH‰UÈH‰uÀI‰þ1ÿH…ÒA½MEîÇEÔI9ör L‰ñ1ÛM‰÷éºI¼L‰ñ1ÛM‰÷AŠ<¸„Àt-< „°< …¸‰ÈD)ø…À~R‹UÔÚ‰UÔM…íuQE1íë>Hƒ}Èt7H…ÿu2ëIÿÇA¶Hƒø;w I£ÄríH…ÀtL‰ÿH5H‹UÈ0ÀèL‰ÿM~ºL‰ùëU…ÛtAÆE IÿÅ»I9ÏsÜL‰èL)øHÁAŠAˆEIÿÇIÿÅ»L9éuéI‰Íë·< uIF…ÒHEÈLEøëIN1ÒIÿÆL;uÀ…ÿÿÿ‰ÈD)ø…À~;‹UÔÚ‰UÔM…ít,…ÛtAÆE IÿÅI9ÏsL‰èL)øHÁAŠAˆEIÿÇIÿÅL9éuî‹EÔHƒÄ[A\A]A^A_]ÃUH‰åAVSƒ=ÿÿÿÿ…£ÇüÿÿÿH=¾0èH H‰ H‰ 8H‰ H‰ 8H=HLL LLL5HH5H‰ H‰ 8H‰ H‰ 8H‰  H‰ 8 H‰ (HH‰ 8(H‰=H‰=89H‰= H‰=89 H‰=H‰=89H‰=H‰=89H‰=!H‰=89!H‰=)H H‰=89)H‰ @H‰ @H‰ @H‰ @H‰ @ H‰ @(H‰HH‰HH‰H(H‰5ØH‰ØH‰Ø L‰5èL‰è L‰ØL‰ `L‰PH‰H‰H‰ [A^]ÃUH‰å]ÃUH‰åAWAVATSA‰öI‰ÿ¿PèH‰ÃH…Û„ÐH‰ß¾PèMcæ1ÿE…öx L‰çèH‰ÇH‰»ÈL‰þL‰âèD‰³à1ÿE…öxL‰çèH‰ÇD‹³àH‰»ÐIcÖH‹³ÈèH‹ƒÐH‰ƒØÇƒðǃôƃìHǃäH‰ƒøH‰ƒH‰ƒH‰ƒHǃ HǃH‰Ø[A\A^A_]ÃUH‰åSPH‰ûH‹»ÐèH‹»ÈèH‰ßHƒÄ[]éUH‰åSPH‰ûH‹»ÐèHc»àH…ÿy1Àë è‹»àH‰ƒÐHc×H‹³ÈH‰ÇèH‹ƒÐH‰ƒØÇƒðǃôƃìHǃäH‰ƒøH‰ƒH‰ƒH‰ƒHǃ HǃHƒÄ[]ÃUH‰åAWAVAUATSPH‰ûLc«àL«ÐL³(IÇF IÇFIÇFIÇFIÇH‹ƒØL=L%ë|L‰«1É‹ƒð‰ÂÁâƒø¸OоƒìÁàÈЃ»è•Á¶ÉÁáÁHcÁH H‹ÁH…ÀtH‰ßÿÐH‹ƒØHÿÀL9èIGÅH‰ƒØƒ»(…ÍL9ès¾…ÉuHÿÀH‰ƒØë胻è~,Aƒ>ˆÇƒ(ÿÿÿÿH‰ß1öHÇÂÿÿÿÿL‰ù0Àèëk€»ìt!Aƒ>x\ǃ(þÿÿÿH‰ß1öHÇÂÿÿÿÿL‰áë̓»ð~8Aƒ>x ǃ(ýÿÿÿH‰ß1öHÇÂÿÿÿÿL‰á0Àè¹}L9«‚ÕþÿÿL9«‚¿þÿÿH‰ßèL‰ðHƒÄ[A\A]A^A_]ÃUH‰åH‹‡ØŠˆ‡ì]ÃUH‰åƇì]ÃUH‰åÿ‡èHLJøH‹‡ØHÿÀH‰‡]ÃUH‰åÿè]ÃUH‰åSPH‰ûH‹³ØH;³Ðv€~ÿ#u ǃôë?H‰³H‹»øH…ÿt1Òè…ÀtH‹ƒøH‰ƒH‰ßèHǃøÿƒðHƒÄ[]ÃUH‰åÿ‡ð]ÃUH‰åSPH‰ûÇEôÿÿÿÿÿ‹ðƒ»ô…¤H‹ƒØH‰ƒ H‹»H‹³HUôè‹Môƒùÿu‹‹ä뉋äH‹“H‰“0‰ƒ8H‹“HÿÂH‰“@H‹ƒ ‰Æ)Ö‰³H‰‹,ǃ(HÿÀH‰ƒH‰ƒH‰ƒHǃøÇƒôHƒÄ[]ÃUH‰åÿð]ÃUH‰åSPH‰ûÇEôÿÿÿÿH‹³ØH‰³H‹»H9÷w{HUôè…ÀtO‹Môƒùÿu‹‹ä뉋äH‹“H‰“0‰ƒ8Hǃ@ǃH‰‹,ǃ(H‹ƒØHÿÀH‰ƒH‰ƒH‰ƒHǃøHƒÄ[]ÃUH‰åSPH‰ûH‹»øH…ÿt H‹³Ø1Òè…ÀtH‹ƒøH‰ƒHǃøH‹ƒØHÿÀH‰ƒHƒÄ[]ÃUH‰åSPH‰ûH‹»øH…ÿt'H‹³Ø1ÒèH‹‹ø…Àt H‰‹ëH…Éu*H‹³ØH‹»1Òè…ÀtH‹ƒØHÿÀH‰ƒøHƒÄ[]ÃUH‰åSPH‰ûÇEôÿÿÿÿH‹³H‹»H9÷wjHUôè…ÀtO‹Môƒùÿu‹‹ä뉋äH‹“H‰“0‰ƒ8Hǃ@ǃH‰‹,ǃ(H‹ƒH‰ƒHƒÄ[]ÃÔ  L\™€' €/³ELÇE( '# à'# &[# .'# Á[# Õ'#  `9 P ¯O# ¸[#È Á[#Ð É[#Ø Õ'#à à'#ä ç' #è ëE!#ì ñ'"#ð ÷'##ô ü[$#ø [%#€ [&#ˆ ['# [(#˜ [)#  ¿*#¨ Ê?+ß  ê ïLW÷Lÿÿ /c'›V`[[‚௠¹'›f[ðl[˜q[-v'|'‰'­…[G‹EÉ'ìjo›WVŸWÓŸRuë‚yW]V˜ê]`VÁ["Õ'Xs`Öƒê„T™„‘‹¦i­¸iéî©¥`V֥ꎺ±EVÖ±êĘEiÐØ¹ÎÍdEVÖÍêúV‹ÐEÛÑ[CçÏy™k’×”Q'¿ ä;˜!š;˜!Ð;Ò !¡;Æ " øQ˜!”Q'!šQ˜!”Q'!¡QÆ # !$’"'$’"'%ƒ= Ñ VÖƒêÂF Ñ &à„'‘tê„'ød Ê m ¼ &à„'‘t&à„'‘t&à„'‘t&à„'‘t&à„'‘t'=Ð = VÖêŒ'Ux Ð VÖêV%mäÁx VÖäêýÊx &àå'‘têå'3ïf øG &àå'‘t&àå'‘t&àå'‘t&àå'‘t&àå'‘t%ˆÚµÁVÖÚêÚ% ¼ÝµVÖ¼êæµ&à½'‘tê½'·¤&à½'‘t&à½'‘t&à½'‘t&à½'‘t&à½'‘t%¹²ÑÝVÖ²ê^%ÓžZÑVÖžê(%îzNZVÖzê% n&NVÖnêâ%,d&VÖdê¿%EZVÖZêœ'§ ´ ¹Z » ÉN(Ñ %Rá $> 4I? : ; $ > I!I/ I : ; I: ; 8 2 I: ;  : ; ' I!I/.: ; ' I? @ : ; I 4: ; I4: ; I .: ;' ? @ 1X Y41 .: ;' ? @ .: ;' I? @ : ;I4: ;I1 1X Y4: ;I 4: ;I: ; I .: ; ' I !: ; I"#.: ;' $ %.: ; ' @ &4: ; I '.: ;' @ (&n\û ./usr/include/secureblock_locator.cblock_locator.h_string.h !  '4Y ¼uužLwÝKÊ× ÖI¾iʼuYK„×Ç]Ÿ  ¸Jõ¡×uu t%trrrrsqs_tuuuuuutjtvuuuuuuuuuuwrvuuuuuvuuvuuvuvvvvuut\ N2  _8Ê}¹Èž8±} Ѭ׭su8­}žÔXÚŸ›$uuuv]¿ •»»Û •»òYeu8„}žý‚ÚŸ›$uuuv]x6 Ü8ü|t†''tt GI[ÉIygÈZu!º‘ŸŸ y‘gŸ ‘gŸ£ÍÎ…·|  På1 Pu1 Pg­1 Og. –Y¼uÖ‘؃®gw Pg1 ‘{gÉ ×gŠy‚i×gg u®Ÿw Pg1 ‘{× ó’Šy‚i×g­Ÿg Ø­w –º!Ø­w –º ÙqK ’#Xƒè~t ‘{ g’Šy‚i×g­Ÿg ØU?^?D_D[^[[_;E^5T5›v@!Q!›vHU7^D[^[[_Ùá_áãR _‰_U7^D[^[[_Ùá_áãR68RUDfU"nU‰›U›ŠŠQ"vT"UUXQX‰vT‰›+7]D[]ïï]]ii]„‰]^fP’PJNP]nUnÆ_]kTkÆ^`iUi‰S˜U˜CSEVUViSròSdi]rê]öPU&U&NUNZUZcUcÏSÑÝUÝæUæ³S%gPµÁUÁÊUÊv SôG Px U Î SÐ Ù UÙ 6 S= F UF Ê Si ¼ PØ Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)block_locator.c/usr/local/www/dubalu/libs/scss/srcfunction_map_initializedintscss_function_mapexcchar_codestrcodestrcodestr_ptrcodestr_szlinenoparinstrdepthskipthininitsafelosestartendblockerrorselpropselprop_szBlockBlockLocator_BlockLocator_Callback_stripBlockLocator_initializeBlockLocator_finalizeBlockLocator_newBlockLocator_delBlockLocator_rewindBlockLocator_iternext__inline_memcpy_chk__inline_memset_chkinit_function_map_BlockLocator_flush_properties_BlockLocator_mark_thin_BlockLocator_mark_safe_BlockLocator_end_property_BlockLocator_end_block_BlockLocator_end_block1_BlockLocator_start_block_BlockLocator_start_block1_BlockLocator_end_parenthesis_BlockLocator_start_parenthesis_BlockLocator_end_string_BlockLocator_start_stringbeginfirstlastlineaddnlpasscntwritec_cnti__val__dest__lenlong unsigned int__darwin_size_tsize_t__srcselfcodestr_endfnlen%dMissing closing parenthesis somewhere in blockMissing closing string somewhere in blockHSAH  ÿÿÿÿ ÿÿÿÿðö”ïïx8´sá;.Ù«ñ€ %*9¬Û† c´s•ÓÙ+M ÇÎÎŽ¦'»1V©Ûív×í´>Û·.«‚1µ]¯úpµ“:ª «S4¡›–z?þ4¡ãÙ>{ 0@Xhxˆ˜¨¸ÌÜìü ,<L\l|Œú ©Fä+°ÓÝ,[ ºs˜‚jmøð9E… c-ÎÊî ˆØ‚f€. 1 ¹³Ué A=½HSAH ÿÿÿÿHSAH ÿÿÿÿHSAH ÿÿÿÿÿÿÿÿÿÿÿÿ0€ˆ °oæ “òÐc •|¤7#«µà&ï½|5û/“ûyˆ›®ÁÔçú ™'$9¿ÉÆ ³E$?ß¹» §´ $L÷f  AŸøøð„9kää­+é°Ð›ÑX›¼!W]  &(N Ñ µ zRx ,ˆÓÿÿÿÿÿÿ›A†C MƒŒŽ$LóÔÿÿÿÿÿÿ¼A†C CƒŽ$t‡ÖÿÿÿÿÿÿA†C ,œeÖÿÿÿÿÿÿA†C GƒŒŽ$Ì8×ÿÿÿÿÿÿ/A†C Bƒ$ô?×ÿÿÿÿÿÿ¶A†C Bƒ,Í×ÿÿÿÿÿÿ¿A†C JƒŒŽ$L\ÙÿÿÿÿÿÿA†C $tIÙÿÿÿÿÿÿ A†C $œ.Ùÿÿÿÿÿÿ(A†C $Ä.Ùÿÿÿÿÿÿ A†C $ìÙÿÿÿÿÿÿwA†C Bƒ$aÙÿÿÿÿÿÿ A†C $<EÙÿÿÿÿÿÿØA†C Bƒ$dõÙÿÿÿÿÿÿ A†C $ŒÙÙÿÿÿÿÿÿ·A†C Bƒ$´hÚÿÿÿÿÿÿXA†C Bƒ$ܘÚÿÿÿÿÿÿmA†C Bƒ$ÝÚÿÿÿÿÿÿ”A†C Bƒe (- (-ï (-— (-ð(-!(-µ-›(-î&-Ç.-l.-î+£œ Ô0-µ,- /-‹/-}/-q/-ê0-Ê,-´0-Ÿ,---t,-N+G+@+9+2+++$++++++ú+ó+ì+å+Þ+×+Ð+É+Â+» ´+­+¦+Ÿ+˜+‘+Š+ƒ+|+u+n+g+` Y+R+K+D+=+6+/+( !  þ÷ðé+â+Û+Ô+ÍÆ--¼+±*¤*mÎ1-Õ  k c A 9   íåûbZ4, èà†~umG?%úòÎÆkcZR,$ F>ûàØ½µ¨ …}XP80 ýõèàËØxpNF91&‚zB:% = jøÝÕʧŸ”Œqi^V;3ýâÚ¿·œ”‰f^C;0( êâÇ¿¤œy^VKC(  úß×ÌÄ©¡–Žsk`X=5*"ÿôìÑÉ®¦›“ˆ€umbZOG+#üðèÜÔÉÁµ­‘‰nf[SH@5- ÿ÷ìäÙÑÆ¾³« ˜}ujbWOD<1) øðÔÌÁ¹•Š‚g_TLA9.& T TTTüTüøTøôTôðTðìTìèTèäTäàTàÜTÜØTØÔTÔÐTÐÌTÌÈTÈÄTÄÀTÀ¼T¼¸T¸´T´°T°„T„€T€|T|xTxtTtpTplTlhThbVJ5) àÀ €`@  J&–²Ì= ìÐ x Á:µSÝmшZ¤NÃ&ä M&ì |&ôX,þ -È-:ð-^.€@.Ÿh.½.Ú¸.öà./10/MX/Ÿ`H -`WÈ,›ý ,ÌEup-w]3ð,·]H-òp,* €/D /‰Wã±— __strip_sscanf_BlockLocator_initialize_function_map_initialized_scss_function_map___bzero_BlockLocator_finalize_BlockLocator_new_PyMem_Malloc_memcpy_BlockLocator_del_free_BlockLocator_rewind_BlockLocator_iternext___sprintf_chk__strip.eh_BlockLocator_initialize.eh_BlockLocator_finalize.eh_BlockLocator_new.eh_BlockLocator_del.eh_BlockLocator_rewind.eh_BlockLocator_iternext.ehL_.str__BlockLocator_start_string__BlockLocator_end_string__BlockLocator_flush_properties__BlockLocator_mark_thin__BlockLocator_mark_safe__BlockLocator_end_property__BlockLocator_end_block__BlockLocator_end_block1__BlockLocator_start_block__BlockLocator_start_block1__BlockLocator_end_parenthesis__BlockLocator_start_parenthesisL_.str1L_.str2EH_frame0__BlockLocator_start_string.eh__BlockLocator_end_string.eh__BlockLocator_start_parenthesis.eh__BlockLocator_end_parenthesis.eh__BlockLocator_start_block1.eh__BlockLocator_start_block.eh__BlockLocator_end_block1.eh__BlockLocator_end_block.eh__BlockLocator_end_property.eh__BlockLocator_mark_safe.eh__BlockLocator_mark_thin.eh__BlockLocator_flush_properties.ehpyScss-1.1.5/scss/src/block_locator.py0000755000076500000240000004445711702633656020440 0ustar kronuzstaff00000000000000#!/usr/bin/env python ## locate_blocks() needs heavy optimizations... is way too slow right now! ## Any suggestion from python wizards? :-) import re import sys from datetime import datetime import pstats import cProfile from cStringIO import StringIO def profile(fn): def wrapper(*args, **kwargs): profiler = cProfile.Profile() stream = StringIO() profiler.enable() try: res = fn(*args, **kwargs) finally: profiler.disable() stats = pstats.Stats(profiler, stream=stream) stats.sort_stats('time') print >>stream, "" print >>stream, "=" * 100 print >>stream, "Stats:" stats.print_stats() print >>stream, "=" * 100 print >>stream, "Callers:" stats.print_callers() print >>stream, "=" * 100 print >>stream, "Callees:" stats.print_callees() print >>sys.stderr, stream.getvalue() stream.close() return res return wrapper DEBUG = False ################################################################################ # Helper functions SEPARATOR = '\x00' _nl_re = re.compile(r'\s*\n\s*', re.MULTILINE) _nl_num_re = re.compile(r'\n.+' + SEPARATOR, re.MULTILINE) _nl_num_nl_re = re.compile(r'\n.+' + SEPARATOR + r'\s*(?=\n)', re.MULTILINE) _blocks_re = re.compile(r'[{},;()\'"\n]') def load_string(codestr): """ Add line numbers to the string using SEPARATOR as the separation between the line number and the line. """ idx = {'line': 1} # Add line numbers: def _cnt(m): idx['line'] += 1 return '\n' + str(idx['line']) + SEPARATOR codestr = str(idx['line']) + SEPARATOR + _nl_re.sub(_cnt, codestr + '\n') # remove empty lines codestr = _nl_num_nl_re.sub('', codestr) return codestr def _strip_selprop(selprop, lineno): # Get the line number of the selector or property and strip all other # line numbers that might still be there (from multiline selectors) _lineno, _sep, selprop = selprop.partition(SEPARATOR) if _sep == SEPARATOR: _lineno = _lineno.strip(' \t\n;') try: lineno = int(_lineno) except ValueError: pass else: selprop = _lineno selprop = _nl_num_re.sub('\n', selprop) selprop = selprop.strip() return selprop, lineno def _strip(selprop): # Strip all line numbers, ignoring them in the way selprop, _ = _strip_selprop(selprop, None) return selprop ################################################################################ # Algorithm implemented in C (much slower here): PAR = 0 INSTR = 1 DEPTH = 2 SKIP = 3 THIN = 4 INIT = 5 SAFE = 6 LOSE = 7 START = 8 END = 9 LINENO = 10 SELPROP = 11 def _start_string(codestr, ctx, i, c): if DEBUG: print "_start_string" # A string starts ctx[INSTR] = c return yield def _end_string(codestr, ctx, i, c): if DEBUG: print "_end_string" # A string ends (FIXME: needs to accept escaped characters) ctx[INSTR] = None return yield def _start_parenthesis(codestr, ctx, i, c): if DEBUG: print "_start_parenthesis" # parenthesis begins: ctx[PAR] += 1 ctx[THIN] = None ctx[SAFE] = i + 1 return yield def _end_parenthesis(codestr, ctx, i, c): if DEBUG: print "_end_parenthesis" ctx[PAR] -= 1 return yield def _flush_properties(codestr, ctx, i, c): if DEBUG: print "_flush_properties" # Flush properties if ctx[LOSE] <= ctx[INIT]: _property, ctx[LINENO] = _strip_selprop(codestr[ctx[LOSE]:ctx[INIT]], ctx[LINENO]) if _property: yield ctx[LINENO], _property, None ctx[SELPROP] = _property ctx[LOSE] = ctx[INIT] return yield def _start_block1(codestr, ctx, i, c): if DEBUG: print "_start_block1" # Start level-1 block if i > 0 and codestr[i - 1] == '#': # Do not process #{...} as blocks! ctx[SKIP] = True else: ctx[START] = i if ctx[THIN] is not None and _strip(codestr[ctx[THIN]:i]): ctx[INIT] = ctx[THIN] for y in _flush_properties(codestr, ctx, i, c): yield y ctx[THIN] = None ctx[DEPTH] += 1 return yield def _start_block(codestr, ctx, i, c): if DEBUG: print "_start_block" # Start blocks: ctx[DEPTH] += 1 return yield def _end_block1(codestr, ctx, i, c): if DEBUG: print "_end_block1" # End level-1 block: ctx[DEPTH] -= 1 if not ctx[SKIP]: ctx[END] = i _selectors, ctx[LINENO] = _strip_selprop(codestr[ctx[INIT]:ctx[START]], ctx[LINENO]) _codestr = codestr[ctx[START] + 1:ctx[END]] if _selectors: yield ctx[LINENO], _selectors, _codestr ctx[SELPROP] = _selectors ctx[INIT] = ctx[SAFE] = ctx[LOSE] = ctx[END] + 1 ctx[THIN] = None ctx[SKIP] = False return yield def _end_block(codestr, ctx, i, c): if DEBUG: print "_end_block" # Block ends: ctx[DEPTH] -= 1 return yield def _end_property(codestr, ctx, i, c): if DEBUG: print "_end_property" # End of property (or block): ctx[INIT] = i if ctx[LOSE] <= ctx[INIT]: _property, ctx[LINENO] = _strip_selprop(codestr[ctx[LOSE]:ctx[INIT]], ctx[LINENO]) if _property: yield ctx[LINENO], _property, None ctx[SELPROP] = _property ctx[INIT] = ctx[SAFE] = ctx[LOSE] = i + 1 ctx[THIN] = None return yield def _mark_safe(codestr, ctx, i, c): if DEBUG: print "_mark_safe" # We are on a safe zone if ctx[THIN] is not None and _strip(codestr[ctx[THIN]:i]): ctx[INIT] = ctx[THIN] ctx[THIN] = None ctx[SAFE] = i + 1 return yield def _mark_thin(codestr, ctx, i, c): if DEBUG: print "_mark_thin" # Step on thin ice, if it breaks, it breaks here if ctx[THIN] is not None and _strip(codestr[ctx[THIN]:i]): ctx[INIT] = ctx[THIN] ctx[THIN] = i + 1 elif ctx[THIN] is None and _strip(codestr[ctx[SAFE]:i]): ctx[THIN] = i + 1 return yield scss_function_map = { # (c, instr, par, depth) ('"', None, False, 0): _start_string, ("'", None, False, 0): _start_string, ('"', None, True, 0): _start_string, ("'", None, True, 0): _start_string, ('"', None, False, 1): _start_string, ("'", None, False, 1): _start_string, ('"', None, True, 1): _start_string, ("'", None, True, 1): _start_string, ('"', None, False, 2): _start_string, ("'", None, False, 2): _start_string, ('"', None, True, 2): _start_string, ("'", None, True, 2): _start_string, ('"', '"', False, 0): _end_string, ("'", "'", False, 0): _end_string, ('"', '"', True, 0): _end_string, ("'", "'", True, 0): _end_string, ('"', '"', False, 1): _end_string, ("'", "'", False, 1): _end_string, ('"', '"', True, 1): _end_string, ("'", "'", True, 1): _end_string, ('"', '"', False, 2): _end_string, ("'", "'", False, 2): _end_string, ('"', '"', True, 2): _end_string, ("'", "'", True, 2): _end_string, ("(", None, False, 0): _start_parenthesis, ("(", None, True, 0): _start_parenthesis, ("(", None, False, 1): _start_parenthesis, ("(", None, True, 1): _start_parenthesis, ("(", None, False, 2): _start_parenthesis, ("(", None, True, 2): _start_parenthesis, (")", None, True, 0): _end_parenthesis, (")", None, True, 1): _end_parenthesis, (")", None, True, 2): _end_parenthesis, ("{", None, False, 0): _start_block1, ("{", None, False, 1): _start_block, ("{", None, False, 2): _start_block, ("}", None, False, 1): _end_block1, ("}", None, False, 2): _end_block, (";", None, False, 0): _end_property, (",", None, False, 0): _mark_safe, ("\n", None, False, 0): _mark_thin, (None, None, False, 0): _flush_properties, (None, None, False, 1): _flush_properties, (None, None, False, 2): _flush_properties, } def _locate_blocks_a(codestr): """ For processing CSS like strings. Either returns all selectors (that can be "smart" multi-lined, as long as it's joined by `,`, or enclosed in `(` and `)`) with its code block (the one between `{` and `}`, which can be nested), or the "lose" code (properties) that doesn't have any blocks. threshold is the number of blank lines before selectors are broken into pieces (properties). """ ctx = [0, None, 0, False, None, 0, 0, 0, None, None, 0, '??'] for m in _blocks_re.finditer(codestr): c = m.group() fn = scss_function_map.get((c, ctx[INSTR], ctx[PAR] != 0, 2 if ctx[DEPTH] > 1 else ctx[DEPTH])) if DEBUG: print fn and ' > ' or ' ', fn and fn.__name__, (c, ctx[INSTR], ctx[PAR] != 0, 2 if ctx[DEPTH] > 1 else ctx[DEPTH]) if fn: for y in fn(codestr, ctx, m.start(), c): yield y codestr_end = len(codestr) exc = None if ctx[PAR]: exc = exc or "Missing closing parenthesis somewhere in block: '%s'" % ctx[SELPROP] elif ctx[INSTR]: exc = exc or "Missing closing string somewhere in block: '%s'" % ctx[SELPROP] elif ctx[DEPTH]: exc = exc or "Block never closed: '%s'" % ctx[SELPROP] while ctx[DEPTH] > 0 and ctx[INIT] < codestr_end: c = '}' fn = scss_function_map.get((c, ctx[INSTR], ctx[PAR] != 0, 2 if ctx[DEPTH] > 1 else ctx[DEPTH])) if DEBUG: print fn and ' > ' or ' ! ', fn and fn.__name__, (c, ctx[INSTR], ctx[PAR] != 0, 2 if ctx[DEPTH] > 1 else ctx[DEPTH]) if fn: for y in fn(codestr, ctx, m.start(), c): yield y if ctx[INIT] < codestr_end: ctx[INIT] = codestr_end c = None fn = scss_function_map.get((c, ctx[INSTR], ctx[PAR] != 0, 2 if ctx[DEPTH] > 1 else ctx[DEPTH])) if DEBUG: print fn and ' > ' or ' ! ', fn and fn.__name__, (c, ctx[INSTR], ctx[PAR] != 0, 2 if ctx[DEPTH] > 1 else ctx[DEPTH]) if fn: for y in fn(codestr, ctx, m.start(), c): yield y if exc: raise Exception(exc) ################################################################################ # Algorithm using Regexps in pure Python (fastest pure python): def _locate_blocks_b(codestr): """ For processing CSS like strings. Either returns all selectors (that can be "smart" multi-lined, as long as it's joined by `,`, or enclosed in `(` and `)`) with its code block (the one between `{` and `}`, which can be nested), or the "lose" code (properties) that doesn't have any blocks. threshold is the number of blank lines before selectors are broken into pieces (properties). """ lineno = 0 par = 0 instr = None depth = 0 skip = False thin = None i = init = safe = lose = 0 start = end = None for m in _blocks_re.finditer(codestr): i = m.start(0) c = codestr[i] if instr is not None: if c == instr: instr = None # A string ends (FIXME: needs to accept escaped characters) elif c in ('"', "'"): instr = c # A string starts elif c == '(': # parenthesis begins: par += 1 thin = None safe = i + 1 elif c == ')': # parenthesis ends: par -= 1 elif not par and not instr: if c == '{': # block begins: if depth == 0: if i > 0 and codestr[i - 1] == '#': # Do not process #{...} as blocks! skip = True else: start = i if thin is not None and _strip(codestr[thin:i]): init = thin if lose <= init: _property, lineno = _strip_selprop(codestr[lose:init], lineno) if _property: yield lineno, _property, None lose = init thin = None depth += 1 elif c == '}': # block ends: if depth > 0: depth -= 1 if depth == 0: if not skip: end = i _selectors, lineno = _strip_selprop(codestr[init:start], lineno) _codestr = codestr[start + 1:end].strip() if _selectors: yield lineno, _selectors, _codestr init = safe = lose = end + 1 thin = None skip = False elif depth == 0: if c == ';': # End of property (or block): init = i if lose <= init: _property, lineno = _strip_selprop(codestr[lose:init], lineno) if _property: yield lineno, _property, None init = safe = lose = i + 1 thin = None elif c == ',': if thin is not None and _strip(codestr[thin:i]): init = thin thin = None safe = i + 1 elif c == '\n': if thin is not None and _strip(codestr[thin:i]): init = thin thin = i + 1 elif thin is None and _strip(codestr[safe:i]): thin = i + 1 # Step on thin ice, if it breaks, it breaks here if depth > 0: if not skip: _selectors, lineno = _strip_selprop(codestr[init:start], lineno) _codestr = codestr[start + 1:].strip() if _selectors: yield lineno, _selectors, _codestr if par: raise Exception("Missing closing parenthesis somewhere in block: '%s'" % _selectors) elif instr: raise Exception("Missing closing string somewhere in block: '%s'" % _selectors) else: raise Exception("Block never closed: '%s'" % _selectors) losestr = codestr[lose:] for _property in losestr.split(';'): _property, lineno = _strip_selprop(_property, lineno) if _property: yield lineno, _property, None ################################################################################ # Algorithm implemented in C: try: from _speedups import locate_blocks as _locate_blocks_c except ImportError: _locate_blocks_c = None print >>sys.stderr, "Scanning acceleration disabled (_speedups not found)!" ################################################################################ codestr = """ simple { block; } #{ignored}; some, selectors, and multi-lined, selectors with more { the block in here; can have, nested, selectors { and properties in nested blocks; and stuff with #{ ignored blocks }; } properties-can: "have strings with stuff like this: }"; } and other, selectors can be turned into "lose" properties if no commas are found however this is a selector ( as well as these things, which are parameters and can expand any number of lines) { and this is its block;; } """ verify = '\t----------------------------------------------------------------------\n\t>[1] \'simple\'\n\t----------------------------------------------------------------------\n\t>\t[3] \'block\'\n\t----------------------------------------------------------------------\n\t>[5] \'#{ignored}\'\n\t----------------------------------------------------------------------\n\t>[6] \'some,\\nselectors,\\nand multi-lined,\\nselectors\'\n\t----------------------------------------------------------------------\n\t>[10] \'with more\'\n\t----------------------------------------------------------------------\n\t>\t[12] \'the block in here\'\n\t----------------------------------------------------------------------\n\t>\t[13] \'can have, nested, selectors\'\n\t----------------------------------------------------------------------\n\t>\t\t[14] \'and properties in nested blocks\'\n\t----------------------------------------------------------------------\n\t>\t\t[15] \'and stuff with #{ ignored blocks }\'\n\t----------------------------------------------------------------------\n\t>\t[17] \'properties-can: "have strings with stuff like this: }"\'\n\t----------------------------------------------------------------------\n\t>[19] \'and other,\\nselectors\\ncan be turned into "lose"\\nproperties\'\n\t----------------------------------------------------------------------\n\t>[23] \'if no commas are found\\nhowever this is a selector (\\nas well as these things,\\nwhich are parameters\\nand can expand\\nany number of\\nlines)\'\n\t----------------------------------------------------------------------\n\t>\t[30] \'and this is its block\'\n' def process_block(locate_blocks, codestr, level=0, dump=False): ret = '' if dump else None for lineno, selprop, block in locate_blocks(codestr): if dump: ret += '\t%s\n\t>%s[%s] %s\n' % ('-' * 70, '\t' * level, lineno, repr(selprop)) if block: _ret = process_block(locate_blocks, block, level + 1, dump) if dump: ret += _ret return ret def process_blocks(locate_blocks, codestr): for q in xrange(20000): process_block(locate_blocks, codestr) profiled_process_blocks = profile(process_blocks) if __name__ == "__main__": codestr = load_string(codestr) for locate_blocks, desc in ( (_locate_blocks_a, "Pure Python, Full algorithm (_locate_blocks_a)"), (_locate_blocks_b, "Pure Python, Condensed algorithm (_locate_blocks_b)"), (_locate_blocks_c, "Builtin C Function, Full algorithm (_locate_blocks_c)"), ): if locate_blocks: ret = process_block(locate_blocks, codestr, dump=True) # print "This is what %s returned:" % desc # print ret # print repr(ret) assert ret == verify, '\nFrom %s, got:\n%s\nShould be:\n%s' % (desc, ret, verify) start = datetime.now() print >>sys.stderr, "Timing: %s..." % desc, process_blocks(locate_blocks, codestr) elap = datetime.now() - start elapms = elap.seconds * 1000.0 + elap.microseconds / 1000.0 print >>sys.stderr, "Done! took %06.3fms" % elapms pyScss-1.1.5/scss/src/build.py0000755000076500000240000000105411700513451016670 0ustar kronuzstaff00000000000000#!/usr/bin/env python import sys from distutils.core import setup, Extension from distutils.command.build_ext import build_ext as _build_ext class build_ext(_build_ext): def finalize_options(self): _build_ext.finalize_options(self) self.build_temp = './' self.build_lib = '../' if len(sys.argv) == 1: sys.argv.append('build') setup(ext_modules=[ Extension( '_speedups', sources=['_speedups.c', 'block_locator.c', 'scanner.c'], libraries=['pcre'], ), ], cmdclass={'build_ext': build_ext}) pyScss-1.1.5/scss/src/grammar/0000755000076500000240000000000012107522130016636 5ustar kronuzstaff00000000000000pyScss-1.1.5/scss/src/grammar/grammar.g0000644000076500000240000002522612106741154020453 0ustar kronuzstaff00000000000000# python yapps2.py grammar.g grammar.py _units = ['em', 'ex', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'deg', 'rad' 'grad', 'ms', 's', 'hz', 'khz', '%'] _inv = lambda s: s ParserValue = lambda s: s NumberValue = lambda s: float(s) StringValue = lambda s: s QuotedStringValue = lambda s: s BooleanValue = lambda s: bool(s) ColorValue = lambda s: s class ListValue(): def __init__(self, v): if isinstance(v, self.__class__): self.v = v else: self.v = {0: v} def first(self): return self.v[0] def __len__(self): return len(self.v) def _reorder_list(lst): return dict((i if isinstance(k, int) else k, v) for i, (k, v) in enumerate(sorted(lst.items()))) def interpolate(v, R): return v def call(fn, args, R, function=True): print 'call: ', fn, args return args ################################################################################ #'(?=" token LT: "<" token GT: ">" token STR: "'[^']*'" token QSTR: '"[^"]*"' token UNITS: "(?>: expr_lst<> {{ v = expr_lst.first() if len(expr_lst) == 1 else expr_lst }} END {{ return v }} rule expr<>: and_test<> {{ v = and_test }} ( OR and_test<> {{ v = and_test if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else (v or and_test) }} )* {{ return v }} rule and_test<>: not_test<> {{ v = not_test }} ( AND not_test<> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else (v and not_test) }} )* {{ return v }} rule not_test<>: comparison<> {{ return comparison }} | ( NOT not_test<> {{ v = 'undefined' if isinstance(not_test, basestring) and (not_test == 'undefined' or not_test.startswith('$')) else (not not_test) }} | INV not_test<> {{ v = 'undefined' if isinstance(not_test, basestring) and (not_test == 'undefined' or not_test.startswith('$')) else _inv('!', not_test) }} )+ {{ return v }} rule comparison<>: a_expr<> {{ v = a_expr }} ( LT a_expr<> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v < a_expr) }} | GT a_expr<> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v > a_expr) }} | LE a_expr<> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v <= a_expr) }} | GE a_expr<> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v >= a_expr) }} | EQ a_expr<> {{ v = (None if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else v) == (None if isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else a_expr) }} | NE a_expr<> {{ v = (None if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else v) != (None if isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else a_expr) }} )* {{ return v }} rule a_expr<>: m_expr<> {{ v = m_expr }} ( ADD m_expr<> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(m_expr, basestring) and (m_expr == 'undefined' or m_expr.startswith('$')) else (v + m_expr) }} | SUB m_expr<> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(m_expr, basestring) and (m_expr == 'undefined' or m_expr.startswith('$')) else (v - m_expr) }} )* {{ return v }} rule m_expr<>: u_expr<> {{ v = u_expr }} ( MUL u_expr<> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else (v * u_expr) }} | DIV u_expr<> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else (v / u_expr) }} )* {{ return v }} rule u_expr<>: SIGN u_expr<> {{ return 'undefined' if isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else _inv('-', u_expr) }} | ADD u_expr<> {{ return 'undefined' if isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else u_expr }} | atom<> {{ v = atom }} [ UNITS {{ v = call(UNITS, ListValue(ParserValue({0: v, 1: UNITS})), R, False) }} ] {{ return v }} rule atom<>: LPAR expr_lst<> RPAR {{ return expr_lst.first() if len(expr_lst) == 1 else expr_lst }} | ID {{ return ID }} | FNCT {{ v = None }} LPAR [ expr_lst<> {{ v = expr_lst }} ] RPAR {{ return call(FNCT, v, R) }} | NUM {{ return NumberValue(ParserValue(NUM)) }} | STR {{ return StringValue(ParserValue(STR)) }} | QSTR {{ return QuotedStringValue(ParserValue(QSTR)) }} | BOOL {{ return BooleanValue(ParserValue(BOOL)) }} | COLOR {{ return ColorValue(ParserValue(COLOR)) }} | VAR {{ return interpolate(VAR, R) }} rule expr_lst<>: {{ n = None }} [ VAR [ ":" {{ n = VAR }} ] {{ else: self._rewind() }} ] expr_slst<> {{ v = {n or 0: expr_slst} }} ( {{ n = None }} COMMA {{ v['_'] = COMMA }} [ VAR [ ":" {{ n = VAR }} ] {{ else: self._rewind() }} ] expr_slst<> {{ v[n or len(v)] = expr_slst }} )* {{ return ListValue(ParserValue(v)) }} rule expr_slst<>: expr<> {{ v = {0: expr} }} ( expr<> {{ v[len(v)] = expr }} )* {{ return ListValue(ParserValue(v)) if len(v) > 1 else v[0] }} %% expr_lst_rsts_ = None ### Grammar ends. ################################################################################ P = Calculator(CalculatorScanner()) def parse(rule, text, *args): P.reset(text) return wrap_error_reporter(P, rule, *args) if __name__ == '__main__': while True: try: s = raw_input('>>> ') except EOFError: break if not s.strip(): break print parse('goal', s, None) print 'Bye.' pyScss-1.1.5/scss/src/grammar/grammar.py0000644000076500000240000003443312106741154020655 0ustar kronuzstaff00000000000000# python yapps2.py grammar.g grammar.py _units = ['em', 'ex', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'deg', 'rad' 'grad', 'ms', 's', 'hz', 'khz', '%'] _inv = lambda s: s ParserValue = lambda s: s NumberValue = lambda s: float(s) StringValue = lambda s: s QuotedStringValue = lambda s: s BooleanValue = lambda s: bool(s) ColorValue = lambda s: s class ListValue(): def __init__(self, v): if isinstance(v, self.__class__): self.v = v else: self.v = {0: v} def first(self): return self.v[0] def __len__(self): return len(self.v) def _reorder_list(lst): return dict((i if isinstance(k, int) else k, v) for i, (k, v) in enumerate(sorted(lst.items()))) def interpolate(v, R): return v def call(fn, args, R, function=True): print 'call: ', fn, args return args ################################################################################ #'(?='), ('LT', '<'), ('GT', '>'), ('STR', "'[^']*'"), ('QSTR', '"[^"]*"'), ('UNITS', '(? a_expr) elif _token_ == 'LE': LE = self._scan('LE') a_expr = self.a_expr(R) v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v <= a_expr) elif _token_ == 'GE': GE = self._scan('GE') a_expr = self.a_expr(R) v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v >= a_expr) elif _token_ == 'EQ': EQ = self._scan('EQ') a_expr = self.a_expr(R) v = (None if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else v) == (None if isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else a_expr) else: # == 'NE' NE = self._scan('NE') a_expr = self.a_expr(R) v = (None if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else v) != (None if isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else a_expr) return v def a_expr(self, R): m_expr = self.m_expr(R) v = m_expr while self._peek(self.a_expr_rsts) in self.a_expr_chks: _token_ = self._peek(self.a_expr_chks) if _token_ == 'ADD': ADD = self._scan('ADD') m_expr = self.m_expr(R) v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(m_expr, basestring) and (m_expr == 'undefined' or m_expr.startswith('$')) else (v + m_expr) else: # == 'SUB' SUB = self._scan('SUB') m_expr = self.m_expr(R) v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(m_expr, basestring) and (m_expr == 'undefined' or m_expr.startswith('$')) else (v - m_expr) return v def m_expr(self, R): u_expr = self.u_expr(R) v = u_expr while self._peek(self.m_expr_rsts) in self.m_expr_chks: _token_ = self._peek(self.m_expr_chks) if _token_ == 'MUL': MUL = self._scan('MUL') u_expr = self.u_expr(R) v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else (v * u_expr) else: # == 'DIV' DIV = self._scan('DIV') u_expr = self.u_expr(R) v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else (v / u_expr) return v def u_expr(self, R): _token_ = self._peek(self.u_expr_rsts) if _token_ == 'SIGN': SIGN = self._scan('SIGN') u_expr = self.u_expr(R) return 'undefined' if isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else _inv('-', u_expr) elif _token_ == 'ADD': ADD = self._scan('ADD') u_expr = self.u_expr(R) return 'undefined' if isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else u_expr else: # in self.u_expr_chks atom = self.atom(R) v = atom if self._peek(self.u_expr_rsts_) == 'UNITS': UNITS = self._scan('UNITS') v = call(UNITS, ListValue(ParserValue({0: v, 1: UNITS})), R, False) return v def atom(self, R): _token_ = self._peek(self.u_expr_chks) if _token_ == 'LPAR': LPAR = self._scan('LPAR') expr_lst = self.expr_lst(R) RPAR = self._scan('RPAR') return expr_lst.first() if len(expr_lst) == 1 else expr_lst elif _token_ == 'ID': ID = self._scan('ID') return ID elif _token_ == 'FNCT': FNCT = self._scan('FNCT') v = None LPAR = self._scan('LPAR') if self._peek(self.atom_rsts) != 'RPAR': expr_lst = self.expr_lst(R) v = expr_lst RPAR = self._scan('RPAR') return call(FNCT, v, R) elif _token_ == 'NUM': NUM = self._scan('NUM') return NumberValue(ParserValue(NUM)) elif _token_ == 'STR': STR = self._scan('STR') return StringValue(ParserValue(STR)) elif _token_ == 'QSTR': QSTR = self._scan('QSTR') return QuotedStringValue(ParserValue(QSTR)) elif _token_ == 'BOOL': BOOL = self._scan('BOOL') return BooleanValue(ParserValue(BOOL)) elif _token_ == 'COLOR': COLOR = self._scan('COLOR') return ColorValue(ParserValue(COLOR)) else: # == 'VAR' VAR = self._scan('VAR') return interpolate(VAR, R) def expr_lst(self, R): n = None if self._peek(self.expr_lst_rsts) == 'VAR': VAR = self._scan('VAR') if self._peek(self.expr_lst_rsts_) == '":"': self._scan('":"') n = VAR else: self._rewind() expr_slst = self.expr_slst(R) v = {n or 0: expr_slst} while self._peek(self.expr_lst_rsts__) == 'COMMA': n = None COMMA = self._scan('COMMA') v['_'] = COMMA if self._peek(self.expr_lst_rsts) == 'VAR': VAR = self._scan('VAR') if self._peek(self.expr_lst_rsts_) == '":"': self._scan('":"') n = VAR else: self._rewind() expr_slst = self.expr_slst(R) v[n or len(v)] = expr_slst return ListValue(ParserValue(v)) def expr_slst(self, R): expr = self.expr(R) v = {0: expr} while self._peek(self.expr_slst_rsts) not in self.expr_lst_rsts__: expr = self.expr(R) v[len(v)] = expr return ListValue(ParserValue(v)) if len(v) > 1 else v[0] not_test_rsts_ = set(['AND', 'LPAR', 'QSTR', 'END', 'COLOR', 'INV', 'SIGN', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'BOOL', 'ID', 'RPAR', 'OR']) m_expr_chks = set(['MUL', 'DIV']) comparison_rsts = set(['LPAR', 'QSTR', 'RPAR', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'COMMA', 'GT', 'END', 'SIGN', 'ADD', 'FNCT', 'STR', 'VAR', 'EQ', 'ID', 'AND', 'INV', 'GE', 'BOOL', 'NOT', 'OR']) atom_rsts = set(['LPAR', 'QSTR', 'COLOR', 'INV', 'SIGN', 'NOT', 'ADD', 'NUM', 'BOOL', 'FNCT', 'STR', 'VAR', 'RPAR', 'ID']) not_test_chks = set(['NOT', 'INV']) u_expr_chks = set(['LPAR', 'COLOR', 'QSTR', 'NUM', 'BOOL', 'FNCT', 'STR', 'VAR', 'ID']) m_expr_rsts = set(['LPAR', 'SUB', 'QSTR', 'RPAR', 'MUL', 'DIV', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'COMMA', 'GT', 'END', 'SIGN', 'GE', 'FNCT', 'STR', 'VAR', 'EQ', 'ID', 'AND', 'INV', 'ADD', 'BOOL', 'NOT', 'OR']) expr_lst_rsts_ = set(['LPAR', 'QSTR', 'COLOR', 'INV', 'SIGN', 'VAR', 'ADD', 'NUM', 'BOOL', '":"', 'STR', 'NOT', 'ID', 'FNCT']) expr_lst_rsts = set(['LPAR', 'QSTR', 'COLOR', 'INV', 'SIGN', 'NOT', 'ADD', 'NUM', 'BOOL', 'FNCT', 'STR', 'VAR', 'ID']) and_test_rsts = set(['AND', 'LPAR', 'QSTR', 'END', 'COLOR', 'INV', 'SIGN', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'BOOL', 'ID', 'RPAR', 'OR']) u_expr_rsts_ = set(['LPAR', 'SUB', 'QSTR', 'RPAR', 'VAR', 'MUL', 'DIV', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'COMMA', 'GT', 'END', 'SIGN', 'GE', 'FNCT', 'STR', 'UNITS', 'EQ', 'ID', 'AND', 'INV', 'ADD', 'BOOL', 'NOT', 'OR']) u_expr_rsts = set(['LPAR', 'COLOR', 'QSTR', 'SIGN', 'ADD', 'NUM', 'BOOL', 'FNCT', 'STR', 'VAR', 'ID']) expr_rsts = set(['LPAR', 'QSTR', 'END', 'COLOR', 'INV', 'SIGN', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'BOOL', 'ID', 'RPAR', 'OR']) not_test_rsts = set(['LPAR', 'QSTR', 'COLOR', 'INV', 'SIGN', 'VAR', 'ADD', 'NUM', 'BOOL', 'FNCT', 'STR', 'NOT', 'ID']) comparison_chks = set(['GT', 'GE', 'NE', 'LT', 'LE', 'EQ']) expr_slst_rsts = set(['LPAR', 'QSTR', 'END', 'COLOR', 'INV', 'RPAR', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'BOOL', 'SIGN', 'ID']) a_expr_chks = set(['ADD', 'SUB']) a_expr_rsts = set(['LPAR', 'SUB', 'QSTR', 'RPAR', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'COMMA', 'GT', 'END', 'SIGN', 'GE', 'FNCT', 'STR', 'VAR', 'EQ', 'ID', 'AND', 'INV', 'ADD', 'BOOL', 'NOT', 'OR']) expr_lst_rsts__ = set(['END', 'COMMA', 'RPAR']) expr_lst_rsts_ = None ### Grammar ends. ################################################################################ P = Calculator(CalculatorScanner()) def parse(rule, text, *args): P.reset(text) return wrap_error_reporter(P, rule, *args) if __name__ == '__main__': while True: try: s = raw_input('>>> ') except EOFError: break if not s.strip(): break print parse('goal', s, None) print 'Bye.' pyScss-1.1.5/scss/src/grammar/LICENSE0000644000076500000240000000202307244430464017656 0ustar kronuzstaff00000000000000Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. pyScss-1.1.5/scss/src/grammar/README0000644000076500000240000000036111674572756017551 0ustar kronuzstaff00000000000000To build the parser from the grammar do: `python ./yapps2.py grammar.g` This will produce `grammar.py`; to that file modify the UNITS to be: '(?= a and b < c) into (a <= b < c) # * Bug fix: identifiers in grammar rules that had digits in them were # not accessible in the {{python code}} section # * Bug fix: made the SyntaxError exception class call # Exception.__init__ (thanks Alex Verstak) # * Style change: replaced raise "string exception" with raise # ClassException(...) (thanks Alex Verstak) from yappsrt import * import sys import re INDENT = " " * 4 class Generator: def __init__(self, name, options, tokens, rules): self.change_count = 0 self.name = name self.options = options self.preparser = '' self.postparser = None self.tokens = {} # Map from tokens to regexps self.sets = {} # Map for restriction sets self.ignore = [] # List of token names to ignore in parsing self.terminals = [] # List of token names (to maintain ordering) for n, t in tokens: if n == '#ignore': n = t self.ignore.append(n) if n in self.tokens.keys() and self.tokens[n] != t: if n not in self.ignore: print 'Warning: token', n, 'multiply defined.' else: self.terminals.append(n) self.tokens[n] = t self.rules = {} # Map from rule names to parser nodes self.params = {} # Map from rule names to parameters self.goals = [] # List of rule names (to maintain ordering) for n, p, r in rules: self.params[n] = p self.rules[n] = r self.goals.append(n) self.output = sys.stdout def __getitem__(self, name): # Get options return self.options.get(name, 0) def non_ignored_tokens(self): return filter(lambda x, i=self.ignore: x not in i, self.terminals) def changed(self): self.change_count = 1 + self.change_count def subset(self, a, b): "See if all elements of a are inside b" for x in a: if x not in b: return 0 return 1 def equal_set(self, a, b): "See if a and b have the same elements" if len(a) != len(b): return 0 if a == b: return 1 return self.subset(a, b) and self.subset(b, a) def add_to(self, parent, additions): "Modify parent to include all elements in additions" for x in additions: if x not in parent: parent.append(x) self.changed() def equate(self, a, b): self.add_to(a, b) self.add_to(b, a) def write(self, *args): for a in args: self.output.write(a) def in_test(self, r, x, full, b): if not b: return '0' if len(b) == 1: return '%s == %s' % (x, repr(b[0])) if full and len(b) > len(full) / 2: # Reverse the sense of the test. not_b = filter(lambda x, b=b: x not in b, full) return self.not_in_test(r, x, full, not_b) n = None for k, v in self.sets.items(): if v == b: n = k if n is None: n = '%s_chks' % r while n in self.sets: n += '_' self.sets[n] = b b_set = 'self.%s' % n return '%s in %s' % (x, b_set) def not_in_test(self, r, x, full, b): if not b: return '1' if len(b) == 1: return '%s != %s' % (x, repr(b[0])) n = None for k, v in self.sets.items(): if v == b: n = k if n is None: n = '%s_chks' % r while n in self.sets: n += '_' self.sets[n] = b b_set = 'self.%s' % n return '%s not in %s' % (x, b_set) def peek_call(self, r, a): n = None for k, v in self.sets.items(): if v == a: n = k if n is None: n = '%s_rsts' % r while n in self.sets: n += '_' self.sets[n] = a a_set = 'self.%s' % n if self.equal_set(a, self.non_ignored_tokens()): a_set = '' if self['context-insensitive-scanner']: a_set = '' return 'self._peek(%s)' % a_set def peek_test(self, r, a, b): if self.subset(a, b): return '1' if self['context-insensitive-scanner']: a = self.non_ignored_tokens() return self.in_test(r, self.peek_call(r, a), a, b) def not_peek_test(self, r, a, b): if self.subset(a, b): return '0' return self.not_in_test(r, self.peek_call(r, a), a, b) def calculate(self): while 1: for r in self.goals: self.rules[r].setup(self, r) if self.change_count == 0: break self.change_count = 0 while 1: for r in self.goals: self.rules[r].update(self) if self.change_count == 0: break self.change_count = 0 def dump_information(self): self.calculate() for r in self.goals: print ' _____' + '_' * len(r) print ('___/Rule ' + r + '\\' + '_' * 80)[:79] queue = [self.rules[r]] while queue: top = queue[0] del queue[0] print repr(top) top.first.sort() top.follow.sort() eps = [] if top.accepts_epsilon: eps = ['(null)'] print ' FIRST:', join(top.first + eps, ', ') print ' FOLLOW:', join(top.follow, ', ') for x in top.get_children(): queue.append(x) def generate_output(self): self.calculate() self.write(self.preparser) # TODO: remove "import *" construct self.write("import re\n") self.write("from string import *\n") self.write("from yappsrt import *\n") self.write("\n\n") self.write("class ", self.name, "Scanner(Scanner):\n") self.write(" patterns = None\n") self.write(" _patterns = [\n") for p in self.terminals: self.write(" (%s, %s),\n" % ( repr(p), repr(self.tokens[p]))) self.write(" ]\n\n") self.write(" def __init__(self, input=None):\n") self.write(" if hasattr(self, 'setup_patterns'):\n") self.write(" self.setup_patterns(self._patterns)\n") self.write(" elif self.patterns is None:\n") self.write(" self.__class__.patterns = []\n") self.write(" for t, p in self._patterns:\n") self.write(" self.patterns.append((t, re.compile(p)))\n") self.write(" super(", self.name, "Scanner, self).__init__(None, %s, input)\n" % repr(self.ignore)) self.write("\n\n") self.write("class ", self.name, "(Parser):\n") for r in self.goals: self.write(INDENT, "def ", r, "(self") if self.params[r]: self.write(", ", self.params[r]) self.write("):\n") self.rules[r].output(self, INDENT + INDENT) self.write("\n") for n, s in self.sets.items(): self.write(" %s = %s\n" % (n, set(s))) if self.postparser is not None: self.write(self.postparser) else: self.write("\n") self.write("P = ", self.name, "(", self.name, "Scanner())\n") self.write("def parse(rule, text, *args):\n") self.write(" P.reset(text)\n") self.write(" return wrap_error_reporter(P, rule, *args)\n") self.write("\n") self.write("if __name__ == '__main__':\n") self.write(INDENT, "from sys import argv, stdin\n") self.write(INDENT, "if len(argv) >= 2:\n") self.write(INDENT * 2, "if len(argv) >= 3:\n") self.write(INDENT * 3, "f = open(argv[2],'r')\n") self.write(INDENT * 2, "else:\n") self.write(INDENT * 3, "f = stdin\n") self.write(INDENT * 2, "print parse(argv[1], f.read())\n") self.write(INDENT, "else: print 'Args: []'\n") ###################################################################### class Node: def __init__(self): self.first = [] self.follow = [] self.accepts_epsilon = 0 self.rule = '?' def setup(self, gen, rule): # Setup will change accepts_epsilon, # sometimes from 0 to 1 but never 1 to 0. # It will take a finite number of steps to set things up self.rule = rule def used(self, vars): "Return two lists: one of vars used, and the other of vars assigned" return vars, [] def get_children(self): "Return a list of sub-nodes" return [] def __repr__(self): return str(self) def update(self, gen): if self.accepts_epsilon: gen.add_to(self.first, self.follow) def output(self, gen, indent): "Write out code to _gen_ with _indent_:string indentation" gen.write(indent, "assert 0 # Invalid parser node\n") class Terminal(Node): def __init__(self, token): Node.__init__(self) self.token = token self.accepts_epsilon = 0 def __str__(self): return self.token def update(self, gen): Node.update(self, gen) if self.first != [self.token]: self.first = [self.token] gen.changed() def output(self, gen, indent): gen.write(indent) if re.match('[a-zA-Z_][a-zA-Z_0-9]*$', self.token): gen.write(self.token, " = ") gen.write("self._scan(%s)\n" % repr(self.token)) class Eval(Node): def __init__(self, expr): Node.__init__(self) self.expr = expr def setup(self, gen, rule): Node.setup(self, gen, rule) if not self.accepts_epsilon: self.accepts_epsilon = 1 gen.changed() def __str__(self): return '{{ %s }}' % self.expr.strip() def output(self, gen, indent): gen.write(indent, self.expr.strip(), '\n') class NonTerminal(Node): def __init__(self, name, args): Node.__init__(self) self.name = name self.args = args def setup(self, gen, rule): Node.setup(self, gen, rule) try: self.target = gen.rules[self.name] if self.accepts_epsilon != self.target.accepts_epsilon: self.accepts_epsilon = self.target.accepts_epsilon gen.changed() except KeyError: # Oops, it's nonexistent print 'Error: no rule <%s>' % self.name self.target = self def __str__(self): return '<%s>' % self.name def update(self, gen): Node.update(self, gen) gen.equate(self.first, self.target.first) gen.equate(self.follow, self.target.follow) def output(self, gen, indent): gen.write(indent) gen.write(self.name, " = ") gen.write("self.", self.name, "(", self.args, ")\n") class Sequence(Node): def __init__(self, *children): Node.__init__(self) self.children = children def setup(self, gen, rule): Node.setup(self, gen, rule) for c in self.children: c.setup(gen, rule) if not self.accepts_epsilon: # If it's not already accepting epsilon, it might now do so. for c in self.children: # any non-epsilon means all is non-epsilon if not c.accepts_epsilon: break else: self.accepts_epsilon = 1 gen.changed() def get_children(self): return self.children def __str__(self): return '( %s )' % join(map(lambda x: str(x), self.children)) def update(self, gen): Node.update(self, gen) for g in self.children: g.update(gen) empty = 1 for g_i in range(len(self.children)): g = self.children[g_i] if empty: gen.add_to(self.first, g.first) if not g.accepts_epsilon: empty = 0 if g_i == len(self.children) - 1: next = self.follow else: next = self.children[1 + g_i].first gen.add_to(g.follow, next) if self.children: gen.add_to(self.follow, self.children[-1].follow) def output(self, gen, indent): if self.children: for c in self.children: c.output(gen, indent) else: # Placeholder for empty sequences, just in case gen.write(indent, 'pass\n') class Choice(Node): def __init__(self, *children): Node.__init__(self) self.children = children def setup(self, gen, rule): Node.setup(self, gen, rule) for c in self.children: c.setup(gen, rule) if not self.accepts_epsilon: for c in self.children: if c.accepts_epsilon: self.accepts_epsilon = 1 gen.changed() def get_children(self): return self.children def __str__(self): return '( %s )' % join(map(lambda x: str(x), self.children), ' | ') def update(self, gen): Node.update(self, gen) for g in self.children: g.update(gen) for g in self.children: gen.add_to(self.first, g.first) gen.add_to(self.follow, g.follow) for g in self.children: gen.add_to(g.follow, self.follow) if self.accepts_epsilon: gen.add_to(self.first, self.follow) def output(self, gen, indent): test = "if" gen.write(indent, "_token_ = ", gen.peek_call(self.rule, self.first), "\n") tokens_seen = [] tokens_unseen = self.first[:] if gen['context-insensitive-scanner']: # Context insensitive scanners can return ANY token, # not only the ones in first. tokens_unseen = gen.non_ignored_tokens() for c in self.children: testset = c.first[:] removed = [] for x in testset: if x in tokens_seen: testset.remove(x) removed.append(x) if x in tokens_unseen: tokens_unseen.remove(x) tokens_seen = tokens_seen + testset if removed: if not testset: print 'Error in rule', self.rule + ':', c, 'never matches.' else: print 'Warning:', self print ' * These tokens are being ignored:', join(removed, ', ') print ' due to previous choices using them.' if testset: if not tokens_unseen: # context sensitive scanners only! if test == 'if': # if it's the first AND last test, then # we can simply put the code without an if/else c.output(gen, indent) else: gen.write(indent, "else:") t = gen.in_test(self.rule, '', [], testset) if len(t) < 70 - len(indent): gen.write(" #", t) gen.write("\n") c.output(gen, indent + INDENT) else: gen.write(indent, test, " ", gen.in_test(self.rule, '_token_', tokens_unseen, testset), ":\n") c.output(gen, indent + INDENT) test = "elif" if gen['context-insensitive-scanner'] and tokens_unseen: gen.write(indent, "else:\n") gen.write(indent, INDENT, "raise SyntaxError(self._pos, ") gen.write("'Could not match ", self.rule, "')\n") class Wrapper(Node): def __init__(self, child): Node.__init__(self) self.child = child def setup(self, gen, rule): Node.setup(self, gen, rule) self.child.setup(gen, rule) def get_children(self): return [self.child] def update(self, gen): Node.update(self, gen) self.child.update(gen) gen.add_to(self.first, self.child.first) gen.equate(self.follow, self.child.follow) class Option(Wrapper): def setup(self, gen, rule): Wrapper.setup(self, gen, rule) if not self.accepts_epsilon: self.accepts_epsilon = 1 gen.changed() def __str__(self): return '[ %s ]' % str(self.child) def output(self, gen, indent): if self.child.accepts_epsilon: print 'Warning in rule', self.rule + ': contents may be empty.' gen.write(indent, "if %s:\n" % gen.peek_test(self.rule, self.first, self.child.first)) self.child.output(gen, indent + INDENT) class Plus(Wrapper): def setup(self, gen, rule): Wrapper.setup(self, gen, rule) if self.accepts_epsilon != self.child.accepts_epsilon: self.accepts_epsilon = self.child.accepts_epsilon gen.changed() def __str__(self): return '%s+' % str(self.child) def update(self, gen): Wrapper.update(self, gen) gen.add_to(self.follow, self.first) def output(self, gen, indent): if self.child.accepts_epsilon: print 'Warning in rule', self.rule + ':' print ' * The repeated pattern could be empty. The resulting' print ' parser may not work properly.' gen.write(indent, "while 1:\n") self.child.output(gen, indent + INDENT) union = self.first[:] gen.add_to(union, self.follow) gen.write(indent + INDENT, "if %s:\n" % gen.not_peek_test(self.rule, union, self.child.first)) gen.write(indent + INDENT * 2, "break\n") class Star(Plus): def setup(self, gen, rule): Wrapper.setup(self, gen, rule) if not self.accepts_epsilon: self.accepts_epsilon = 1 gen.changed() def __str__(self): return '%s*' % str(self.child) def output(self, gen, indent): if self.child.accepts_epsilon: print 'Warning in rule', self.rule + ':' print ' * The repeated pattern could be empty. The resulting' print ' parser probably will not work properly.' gen.write(indent, "while %s:\n" % gen.peek_test(self.rule, self.follow, self.child.first)) self.child.output(gen, indent + INDENT) ###################################################################### # The remainder of this file is from parsedesc.{g,py} def append(lst, x): "Imperative append" lst.append(x) return lst def add_inline_token(tokens, str): tokens.insert(0, (str, eval(str, {}, {}))) return Terminal(str) def cleanup_choice(lst): if len(lst) == 0: return Sequence([]) if len(lst) == 1: return lst[0] return apply(Choice, tuple(lst)) def cleanup_sequence(lst): if len(lst) == 1: return lst[0] return apply(Sequence, tuple(lst)) def cleanup_rep(node, rep): if rep == 'star': return Star(node) elif rep == 'plus': return Plus(node) else: return node def resolve_name(tokens, id, args): if id in map(lambda x: x[0], tokens): # It's a token if args: print 'Warning: ignoring parameters on TOKEN %s<<%s>>' % (id, args) return Terminal(id) else: # It's a name, so assume it's a nonterminal return NonTerminal(id, args) from string import * from yappsrt import * class ParserDescriptionScanner(Scanner): def __init__(self, str): Scanner.__init__(self, [ ('"rule"', 'rule'), ('"ignore"', 'ignore'), ('"token"', 'token'), ('"option"', 'option'), ('":"', ':'), ('"parser"', 'parser'), ('[ \011\015\012]+', '[ \011\015\012]+'), ('#.*?\015?\012', '#.*?\015?\012'), ('END', '$'), ('ATTR', '<<.+?>>'), ('STMT', '{{.+?}}'), ('ID', '[a-zA-Z_][a-zA-Z_0-9]*'), ('STR', '[rR]?\'([^\\n\'\\\\]|\\\\.)*\'|[rR]?"([^\\n"\\\\]|\\\\.)*"'), ('LP', '\\('), ('RP', '\\)'), ('LB', '\\['), ('RB', '\\]'), ('OR', '[|]'), ('STAR', '[*]'), ('PLUS', '[+]'), ], ['[ \011\015\012]+', '#.*?\015?\012'], str) class ParserDescription(Parser): def Parser(self): self._scan('"parser"') ID = self._scan('ID') self._scan('":"') Options = self.Options() Tokens = self.Tokens() Rules = self.Rules(Tokens) END = self._scan('END') return Generator(ID, Options, Tokens, Rules) def Options(self): opt = {} while self._peek(set(['"option"', '"token"', '"ignore"', 'END', '"rule"'])) == '"option"': self._scan('"option"') self._scan('":"') Str = self.Str() opt[Str] = 1 return opt def Tokens(self): tok = [] while self._peek(set(['"token"', '"ignore"', 'END', '"rule"'])) in ['"token"', '"ignore"']: _token_ = self._peek(set(['"token"', '"ignore"'])) if _token_ == '"token"': self._scan('"token"') ID = self._scan('ID') self._scan('":"') Str = self.Str() tok.append((ID, Str)) else: # == '"ignore"' self._scan('"ignore"') self._scan('":"') Str = self.Str() tok.append(('#ignore', Str)) return tok def Rules(self, tokens): rul = [] while self._peek(set(['"rule"', 'END'])) == '"rule"': self._scan('"rule"') ID = self._scan('ID') OptParam = self.OptParam() self._scan('":"') ClauseA = self.ClauseA(tokens) rul.append((ID, OptParam, ClauseA)) return rul def ClauseA(self, tokens): ClauseB = self.ClauseB(tokens) v = [ClauseB] while self._peek(set(['OR', 'RP', 'RB', '"rule"', 'END'])) == 'OR': OR = self._scan('OR') ClauseB = self.ClauseB(tokens) v.append(ClauseB) return cleanup_choice(v) def ClauseB(self, tokens): v = [] while self._peek(set(['STR', 'ID', 'LP', 'LB', 'STMT', 'OR', 'RP', 'RB', '"rule"', 'END'])) in ['STR', 'ID', 'LP', 'LB', 'STMT']: ClauseC = self.ClauseC(tokens) v.append(ClauseC) return cleanup_sequence(v) def ClauseC(self, tokens): ClauseD = self.ClauseD(tokens) _token_ = self._peek(set(['PLUS', 'STAR', 'STR', 'ID', 'LP', 'LB', 'STMT', 'OR', 'RP', 'RB', '"rule"', 'END'])) if _token_ == 'PLUS': PLUS = self._scan('PLUS') return Plus(ClauseD) elif _token_ == 'STAR': STAR = self._scan('STAR') return Star(ClauseD) else: return ClauseD def ClauseD(self, tokens): _token_ = self._peek(set(['STR', 'ID', 'LP', 'LB', 'STMT'])) if _token_ == 'STR': STR = self._scan('STR') t = (STR, eval(STR, {}, {})) if t not in tokens: tokens.insert(0, t) return Terminal(STR) elif _token_ == 'ID': ID = self._scan('ID') OptParam = self.OptParam() return resolve_name(tokens, ID, OptParam) elif _token_ == 'LP': LP = self._scan('LP') ClauseA = self.ClauseA(tokens) RP = self._scan('RP') return ClauseA elif _token_ == 'LB': LB = self._scan('LB') ClauseA = self.ClauseA(tokens) RB = self._scan('RB') return Option(ClauseA) else: # == 'STMT' STMT = self._scan('STMT') return Eval(STMT[2:-2]) def OptParam(self): if self._peek(set(['ATTR', '":"', 'PLUS', 'STAR', 'STR', 'ID', 'LP', 'LB', 'STMT', 'OR', 'RP', 'RB', '"rule"', 'END'])) == 'ATTR': ATTR = self._scan('ATTR') return ATTR[2:-2] return '' def Str(self): STR = self._scan('STR') return eval(STR, {}, {}) # This replaces the default main routine yapps_options = [ ('context-insensitive-scanner', 'context-insensitive-scanner', 'Scan all tokens (see docs)') ] def generate(inputfilename, outputfilename='', dump=0, **flags): """Generate a grammar, given an input filename (X.g) and an output filename (defaulting to X.py).""" if not outputfilename: if inputfilename[-2:] == '.g': outputfilename = inputfilename[:-2] + '.py' else: raise Exception("Missing output filename") print 'Input Grammar:', inputfilename print 'Output File:', outputfilename DIVIDER = '\n%%\n' # This pattern separates the pre/post parsers preparser, postparser = None, None # Code before and after the parser desc # Read the entire file s = open(inputfilename, 'r').read() # See if there's a separation between the pre-parser and parser f = find(s, DIVIDER) if f >= 0: preparser, s = s[:f] + '\n\n', s[f + len(DIVIDER):] # See if there's a separation between the parser and post-parser f = find(s, DIVIDER) if f >= 0: s, postparser = s[:f], '\n\n' + s[f + len(DIVIDER):] # Create the parser and scanner p = ParserDescription(ParserDescriptionScanner(s)) if not p: return # Now parse the file t = wrap_error_reporter(p, 'Parser') if not t: return # Error if preparser is not None: t.preparser = preparser if postparser is not None: t.postparser = postparser # Check the options for f in t.options.keys(): for opt, _, _ in yapps_options: if f == opt: break else: print 'Warning: unrecognized option', f # Add command line options to the set for f in flags.keys(): t.options[f] = flags[f] # Generate the output if dump: t.dump_information() else: t.output = open(outputfilename, 'w') t.generate_output() if __name__ == '__main__': import getopt optlist, args = getopt.getopt(sys.argv[1:], 'f:', ['dump']) if not args or len(args) > 2: print 'Usage:' print ' python', sys.argv[0], '[flags] input.g [output.py]' print 'Flags:' print (' --dump' + ' ' * 40)[:35] + 'Dump out grammar information' for flag, _, doc in yapps_options: print (' -f' + flag + ' ' * 40)[:35] + doc else: # Read in the options and create a list of flags flags = {} for opt in optlist: for flag, name, _ in yapps_options: if opt == ('-f', flag): flags[name] = 1 break else: if opt == ('--dump', ''): flags['dump'] = 1 else: print 'Warning: unrecognized option', opt[0], opt[1] apply(generate, tuple(args), flags) pyScss-1.1.5/scss/src/grammar/yappsrt.py0000644000076500000240000002147411677367455020756 0ustar kronuzstaff00000000000000# Yapps 3.0 Runtime (by Kronuz) # # This module is needed to run generated parsers. import re try: from _scss import Scanner, NoMoreTokens except ImportError: Scanner = None ################################################################################ # Parser if not Scanner: class NoMoreTokens(Exception): """ Another exception object, for when we run out of tokens """ pass class Scanner(object): def __init__(self, patterns, ignore, input=None): """ Patterns is [(terminal,regex)...] Ignore is [terminal,...]; Input is a string """ self.reset(input) self.ignore = ignore # The stored patterns are a pair (compiled regex,source # regex). If the patterns variable passed in to the # constructor is None, we assume that the class already has a # proper .patterns list constructed if patterns is not None: self.patterns = [] for k, r in patterns: self.patterns.append((k, re.compile(r))) def reset(self, input): self.tokens = [] self.restrictions = [] self.input = input self.pos = 0 def __repr__(self): """ Print the last 10 tokens that have been scanned in """ output = '' for t in self.tokens[-10:]: output = "%s\n (@%s) %s = %s" % (output, t[0], t[2], repr(t[3])) return output def _scan(self, restrict): """ Should scan another token and add it to the list, self.tokens, and add the restriction to self.restrictions """ # Keep looking for a token, ignoring any in self.ignore token = None while True: best_pat = None # Search the patterns for a match, with earlier # tokens in the list having preference best_pat_len = 0 for p, regexp in self.patterns: # First check to see if we're restricting to this token if restrict and p not in restrict and p not in self.ignore: continue m = regexp.match(self.input, self.pos) if m: # We got a match best_pat = p best_pat_len = len(m.group(0)) break # If we didn't find anything, raise an error if best_pat is None: msg = "Bad Token" if restrict: msg = "Trying to find one of " + ", ".join(restrict) raise SyntaxError("SyntaxError[@ char %s: %s]" % (repr(self.pos), msg)) # If we found something that isn't to be ignored, return it if best_pat in self.ignore: # This token should be ignored... self.pos += best_pat_len else: end_pos = self.pos + best_pat_len # Create a token with this data token = ( self.pos, end_pos, best_pat, self.input[self.pos:end_pos] ) break if token is not None: self.pos = token[1] # Only add this token if it's not in the list # (to prevent looping) if not self.tokens or token != self.tokens[-1]: self.tokens.append(token) self.restrictions.append(restrict) return 1 return 0 def token(self, i, restrict=None): """ Get the i'th token, and if i is one past the end, then scan for another token; restrict is a list of tokens that are allowed, or 0 for any token. """ tokens_len = len(self.tokens) if i == tokens_len: # We are at the end, get the next... tokens_len += self._scan(restrict) if i < tokens_len: if restrict and self.restrictions[i] and restrict > self.restrictions[i]: raise NotImplementedError("Unimplemented: restriction set changed") return self.tokens[i] raise NoMoreTokens def rewind(self, i): tokens_len = len(self.tokens) if i <= tokens_len: token = self.tokens[i] self.tokens = self.tokens[:i] self.restrictions = self.restrictions[:i] self.pos = token[0] class CachedScanner(Scanner): """ Same as Scanner, but keeps cached tokens for any given input """ _cache_ = {} _goals_ = ['END'] @classmethod def cleanup(cls): cls._cache_ = {} def __init__(self, patterns, ignore, input=None): try: self._tokens = self._cache_[input] except KeyError: self._tokens = None self.__tokens = {} self.__input = input super(CachedScanner, self).__init__(patterns, ignore, input) def reset(self, input): try: self._tokens = self._cache_[input] except KeyError: self._tokens = None self.__tokens = {} self.__input = input super(CachedScanner, self).reset(input) def __repr__(self): if self._tokens is None: return super(CachedScanner, self).__repr__() output = '' for t in self._tokens[-10:]: output = "%s\n (@%s) %s = %s" % (output, t[0], t[2], repr(t[3])) return output def token(self, i, restrict=None): if self._tokens is None: token = super(CachedScanner, self).token(i, restrict) self.__tokens[i] = token if token[2] in self._goals_: # goal tokens self._cache_[self.__input] = self._tokens = self.__tokens return token else: token = self._tokens.get(i) if token is None: raise NoMoreTokens return token def rewind(self, i): if self._tokens is None: super(CachedScanner, self).rewind(i) class Parser(object): def __init__(self, scanner): self._scanner = scanner self._pos = 0 def reset(self, input): self._scanner.reset(input) self._pos = 0 def _peek(self, types): """ Returns the token type for lookahead; if there are any args then the list of args is the set of token types to allow """ tok = self._scanner.token(self._pos, types) return tok[2] def _scan(self, type): """ Returns the matched text, and moves to the next token """ tok = self._scanner.token(self._pos, set([type])) if tok[2] != type: raise SyntaxError("SyntaxError[@ char %s: %s]" % (repr(tok[0]), "Trying to find " + type)) self._pos += 1 return tok[3] def _rewind(self, n=1): self._pos -= min(n, self._pos) self._scanner.rewind(self._pos) ################################################################################ def print_error(input, err, scanner): """This is a really dumb long function to print error messages nicely.""" p = err.pos # Figure out the line number line = input[:p].count('\n') print err.msg + " on line " + repr(line + 1) + ":" # Now try printing part of the line text = input[max(p - 80, 0): p + 80] p = p - max(p - 80, 0) # Strip to the left i = text[:p].rfind('\n') j = text[:p].rfind('\r') if i < 0 or (0 <= j < i): i = j if 0 <= i < p: p = p - i - 1 text = text[i + 1:] # Strip to the right i = text.find('\n', p) j = text.find('\r', p) if i < 0 or (0 <= j < i): i = j if i >= 0: text = text[:i] # Now shorten the text while len(text) > 70 and p > 60: # Cut off 10 chars text = "..." + text[10:] p = p - 7 # Now print the string, along with an indicator print '> ', text print '> ', ' ' * p + '^' print 'List of nearby tokens:', scanner def wrap_error_reporter(parser, rule, *args): try: return getattr(parser, rule)(*args) except SyntaxError, s: input = parser._scanner.input try: print_error(input, s, parser._scanner) raise except ImportError: print "Syntax Error %s on line %d" % (s.msg, input[:s.pos].count('\n') + 1) except NoMoreTokens: print "Could not complete parsing; stopped around here:" print parser._scanner pyScss-1.1.5/scss/src/scanner.c0000644000076500000240000002475511713616362017037 0ustar kronuzstaff00000000000000/* * pyScss, a Scss compiler for Python * SCSS blocks scanner. * * German M. Bravo (Kronuz) * https://github.com/Kronuz/pyScss * * MIT license (http://www.opensource.org/licenses/mit-license.php) * Copyright (c) 2011 German M. Bravo (Kronuz), All rights reserved. */ #include #include #include #include "scanner.h" #include "utils.h" int Pattern_patterns_sz = 0; int Pattern_patterns_bsz = 0; Pattern *Pattern_patterns = NULL; int Pattern_patterns_initialized = 0; Pattern* Pattern_regex(char *tok, char *expr) { int j; #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif for (j = 0; j < Pattern_patterns_sz; j++) { if (strcmp(Pattern_patterns[j].tok, tok) == 0) { return &Pattern_patterns[j]; } } if (expr) { if (j >= Pattern_patterns_bsz) { /* Needs to expand block */ Pattern_patterns_bsz = Pattern_patterns_bsz + BLOCK_SIZE_PATTERNS; PyMem_Resize(Pattern_patterns, Pattern, Pattern_patterns_bsz); } Pattern_patterns[j].tok = PyMem_Strdup(tok); Pattern_patterns[j].expr = PyMem_Strdup(expr); Pattern_patterns[j].pattern = NULL; Pattern_patterns_sz = j + 1; return &Pattern_patterns[j]; } return NULL; } static int Pattern_match(Pattern *regex, char *string, int string_sz, int start_at, Token *p_token) { int options = PCRE_ANCHORED; const char *errptr; int ret, erroffset, ovector[3]; pcre *p_pattern = regex->pattern; #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif if (p_pattern == NULL) { #ifdef DEBUG fprintf(stderr, "\tpcre_compile %s\n", repr(regex->expr)); #endif p_pattern = regex->pattern = pcre_compile(regex->expr, options, &errptr, &erroffset, NULL); } ret = pcre_exec( p_pattern, NULL, /* no extra data */ string, string_sz, start_at, PCRE_ANCHORED, /* default options */ ovector, /* output vector for substring information */ 3 /* number of elements in the output vector */ ); if (ret >= 0) { if (p_token) { p_token->regex = regex; p_token->string = string + ovector[0]; p_token->string_sz = ovector[1] - ovector[0]; } return 1; } return 0; } static void Pattern_initialize(Pattern *, int); static void Pattern_setup(Pattern *, int); static void Pattern_finalize(void); static void Pattern_initialize(Pattern *patterns, int patterns_sz) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif if (!Pattern_patterns_initialized) { if (patterns_sz) { Pattern_patterns_initialized = 1; Pattern_setup(patterns, patterns_sz); } } } static void Pattern_setup(Pattern *patterns, int patterns_sz) { int i; Pattern *regex; #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif if (!Pattern_patterns_initialized) { Pattern_initialize(patterns, patterns_sz); } else { for (i = 0; i < patterns_sz; i++) { regex = Pattern_regex(patterns[i].tok, patterns[i].expr); #ifdef DEBUG if (regex) { fprintf(stderr, "\tAdded regex pattern %s: %s\n", repr(regex->tok), repr(regex->expr)); } #endif } } } static void Pattern_finalize(void) { int j; #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif if (Pattern_patterns_initialized) { for (j = 0; j < Pattern_patterns_sz; j++) { PyMem_Del(Pattern_patterns[j].tok); PyMem_Del(Pattern_patterns[j].expr); if (Pattern_patterns[j].pattern != NULL) { pcre_free(Pattern_patterns[j].pattern); } } PyMem_Del(Pattern_patterns); Pattern_patterns = NULL; Pattern_patterns_sz = 0; Pattern_patterns_bsz = 0; Pattern_patterns_initialized = 0; } } /* Scanner */ static long _Scanner_scan(Scanner *self, Pattern *restrictions, int restrictions_sz) { Token best_token, *p_token; Restriction *p_restriction; Pattern *regex; int j, k, max, skip; #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif while (1) { best_token.regex = NULL; /* Search the patterns for a match, with earlier tokens in the list having preference */ for (j = 0; j < Pattern_patterns_sz; j++) { Pattern *regex = &Pattern_patterns[j]; #ifdef DEBUG fprintf(stderr, "\tTrying %s: %s at pos %d -> %s\n", repr(regex->tok), repr(regex->expr), self->pos, repr(self->input)); #endif /* First check to see if we're restricting to this token */ skip = restrictions_sz; if (skip) { max = (restrictions_sz > self->ignore_sz) ? restrictions_sz : self->ignore_sz; for (k = 0; k < max; k++) { if (k < restrictions_sz && regex == Pattern_regex(restrictions[k].tok, restrictions[k].expr)) { skip = 0; break; } if (k < self->ignore_sz && regex == self->ignore[k]) { skip = 0; break; } } if (skip) { continue; #ifdef DEBUG fprintf(stderr, "\tSkipping!\n"); #endif } } if (Pattern_match( regex, self->input, self->input_sz, self->pos, &best_token )) { #ifdef DEBUG fprintf(stderr, "\tMatch OK! %s: %s at pos %d\n", repr(regex->tok), repr(regex->expr), self->pos); #endif break; } } /* If we didn't find anything, raise an error */ if (best_token.regex == NULL) { if (restrictions_sz) { sprintf(self->exc, "SyntaxError[@ char %d: Trying to find one of the %d restricted tokens!]", self->pos, restrictions_sz); return SCANNER_EXC_RESTRICTED; } sprintf(self->exc, "SyntaxError[@ char %d: Bad Token!]", self->pos); return SCANNER_EXC_BAD_TOKEN; } /* If we found something that isn't to be ignored, return it */ skip = 0; for (k = 0; k < self->ignore_sz; k++) { if (best_token.regex == self->ignore[k]) { /* This token should be ignored... */ self->pos += best_token.string_sz; skip = 1; break; } } if (!skip) { break; } } if (best_token.regex) { self->pos = (int)(best_token.string - self->input + best_token.string_sz); /* Only add this token if it's not in the list (to prevent looping) */ p_token = &self->tokens[self->tokens_sz - 1]; if (self->tokens_sz == 0 || p_token->regex != best_token.regex || p_token->string != best_token.string || p_token->string_sz != best_token.string_sz ) { if (self->tokens_sz >= self->tokens_bsz) { /* Needs to expand block */ self->tokens_bsz = self->tokens_bsz + BLOCK_SIZE_PATTERNS; PyMem_Resize(self->tokens, Token, self->tokens_bsz); PyMem_Resize(self->restrictions, Restriction, self->tokens_bsz); } memcpy(&self->tokens[self->tokens_sz], &best_token, sizeof(Token)); p_restriction = &self->restrictions[self->tokens_sz]; if (restrictions_sz) { p_restriction->patterns = PyMem_New(Pattern *, restrictions_sz); p_restriction->patterns_sz = 0; for (j = 0; j < restrictions_sz; j++) { regex = Pattern_regex(restrictions[k].tok, restrictions[k].expr); if (regex) { p_restriction->patterns[p_restriction->patterns_sz++] = regex; } } } else { p_restriction->patterns = NULL; p_restriction->patterns_sz = 0; } self->tokens_sz++; return 1; } } return 0; } /* Scanner public interface */ void Scanner_reset(Scanner *self, char *input, int input_sz) { int i; #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif for (i = 0; i < self->tokens_sz; i++) { PyMem_Del(self->tokens[i].string); PyMem_Del(self->restrictions[i].patterns); } self->tokens_sz = 0; if (input_sz) { if (self->input) PyMem_Del(self->input); self->input = PyMem_Strndup(input, input_sz); self->input_sz = input_sz; #ifdef DEBUG fprintf(stderr, "Scanning in %s\n", repr(self->input)); #endif } self->pos = 0; } void Scanner_del(Scanner *self) { int i; #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif if (self->ignore != NULL) { PyMem_Del(self->ignore); } if (self->tokens != NULL) { for (i = 0; i < self->tokens_sz; i++) { PyMem_Del(self->restrictions[i].patterns); } PyMem_Del(self->tokens); PyMem_Del(self->restrictions); } if (self->input != NULL) { PyMem_Del(self->input); } PyMem_Del(self); } Scanner* Scanner_new(Pattern patterns[], int patterns_sz, Pattern ignore[], int ignore_sz, char *input, int input_sz) { int i; Scanner *self; Pattern *regex; #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif self = PyMem_New(Scanner, 1); memset(self, 0, sizeof(Scanner)); if (self) { for (i = 0; i < patterns_sz; i++) { regex = Pattern_regex(patterns[i].tok, patterns[i].expr); #ifdef DEBUG if (regex) { fprintf(stderr, "\tAdded regex pattern %s: %s\n", repr(regex->tok), repr(regex->expr)); } #endif } if (ignore_sz) { self->ignore = PyMem_New(Pattern *, ignore_sz); for (i = 0; i < ignore_sz; i++) { regex = Pattern_regex(ignore[i].tok, ignore[i].expr); if (regex) { self->ignore[self->ignore_sz++] = regex; #ifdef DEBUG fprintf(stderr, "\tIgnoring token %s\n", repr(regex->tok)); #endif } } } else { self->ignore = NULL; } Scanner_reset(self, input, input_sz); } return self; } int Scanner_initialized(void) { return Pattern_patterns_initialized; } void Scanner_initialize(Pattern patterns[], int patterns_sz) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif Pattern_initialize(patterns, patterns_sz); } void Scanner_finalize(void) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif Pattern_finalize(); } Token* Scanner_token(Scanner *self, int i, Pattern restrictions[], int restrictions_sz) { int j, k, found; Pattern *regex; long result; #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif if (i == self->tokens_sz) { result = _Scanner_scan(self, restrictions, restrictions_sz); if (result < 0) { return (Token *)result; } } else if (i >= 0 && i < self->tokens_sz) { if (self->restrictions[i].patterns_sz) { for (j = 0; j < restrictions_sz; j++) { found = 0; for (k = 0; k < self->restrictions[i].patterns_sz; k++) { regex = Pattern_regex(restrictions[j].tok, restrictions[j].expr); if (regex == self->restrictions[i].patterns[k]) { found = 1; break; } } if (!found) { sprintf(self->exc, "Unimplemented: restriction set changed"); return (Token *)SCANNER_EXC_UNIMPLEMENTED; } } } } if (i >= 0 && i < self->tokens_sz) { return &self->tokens[i]; } return (Token *)SCANNER_EXC_NO_MORE_TOKENS; } void Scanner_rewind(Scanner *self, int i) { #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif if (i >= 0 && i < self->tokens_sz) { self->tokens_sz = i; self->pos = (int)(self->tokens[i].string - self->input); } } pyScss-1.1.5/scss/src/scanner.h0000644000076500000240000000262511677365210017036 0ustar kronuzstaff00000000000000/* * pyScss, a Scss compiler for Python * SCSS blocks scanner. * * German M. Bravo (Kronuz) * https://github.com/Kronuz/pyScss * * MIT license (http://www.opensource.org/licenses/mit-license.php) * Copyright (c) 2011 German M. Bravo (Kronuz), All rights reserved. */ #ifndef SCANNER_H #define SCANNER_H #define PCRE_STATIC #include #define BLOCK_SIZE_PATTERNS 50 #define BLOCK_SIZE_TOKENS 50 #define MAX_EXC_STRING 200 #define SCANNER_EXC_BAD_TOKEN (long)-1 #define SCANNER_EXC_RESTRICTED (long)-2 #define SCANNER_EXC_UNIMPLEMENTED (long)-3 #define SCANNER_EXC_NO_MORE_TOKENS (long)-4 typedef struct { char *tok; char *expr; pcre *pattern; } Pattern; typedef struct { Pattern *regex; char *string; int string_sz; } Token; typedef struct { int patterns_sz; Pattern **patterns; } Restriction; typedef struct { char exc[MAX_EXC_STRING]; int ignore_sz; Pattern **ignore; int tokens_sz; int tokens_bsz; Token *tokens; Restriction *restrictions; int input_sz; char *input; int pos; } Scanner; int Scanner_initialized(void); void Scanner_initialize(Pattern *, int); void Scanner_finalize(void); void Scanner_reset(Scanner *self, char *input, int input_sz); Scanner *Scanner_new(Pattern *, int, Pattern *, int, char *, int); void Scanner_del(Scanner *); Token* Scanner_token(Scanner *, int, Pattern *, int); void Scanner_rewind(Scanner *, int); #endif pyScss-1.1.5/scss/src/scanner.o0000644000076500000240000013502012034740572017035 0ustar kronuzstaff00000000000000Êþº¾M `Z Îúíþ4 Ì\XPH0__text__TEXTX P˜6…€__debug_info__DWARFX \ ¨À:N__debug_abbrev__DWARF´‰__debug_aranges__DWARF=__debug_macinfo__DWARF=__debug_line__DWARF=Ž0=__debug_loc__DWARFË#8=$__debug_pubtypes__DWARFÍ$+__debug_str__DWARFß$Í/+__debug_ranges__DWARF¬(ü.XF__data__DATAÄ(/__bss__DATAH0(__cstring__TEXTÄ(¥/__common__DATALX__apple_names__DWARFi)й/xF4__apple_objc__DWARF9,$‰2__apple_namespac__DWARF],$­2__apple_types__DWARF,}Ñ2H__debug_inlined__DWARFþ-ŽN4ÈH __pointers__IMPORTŒ.Ü4__debug_frame__DWARF”.´ä4IˆI!Kì P €IU‰åSWVƒì 1À‹]…Ût0‹} 1À‰ùAx"‰ $èÜÿÿÿ‰Æ1À…öt‰|$‰\$‰4$èÄÿÿÿ‰ðÆ8ƒÄ ^_[]ÃU‰åVƒì‹u‰4$è¤ÿÿÿ‰D$‰4$è˜ÿÿÿƒÄ^]ÃU‰åSWVƒì<è^‹M ‹U< ‰}ð¸9×v/Š€û&€û t€û t€û t€ûƒÀë €û'uñƒÀë@BIuÑ=(¹(Fȉò‹‚ÌWÁù(r Ç‚ÌW1ÀÆ„Ì/'´Í/„Ì/‰EÔºÌW‚Q(‰Eì‚N(‰Eè‚K(‰Eä‚T(‰Eà‚H(‰E܉UØ‹]ëˆFC;]ðƒ¬¾ƒø&< tS< tC< uWF9øƒ‹Eäë<'uCF9øs}‹E܉D$ ‰4$ÇD$ÿÿÿÿÇD$èeþÿÿƒÆë£F9øsR‹EèëÓF9øsF‹EìëÇ<2N9ùs6‰D$‹Eà‰D$ ‰4$ÇD$ÿÿÿÿÇD$èþÿÿƒÆéUÿÿÿN9ù‚GÿÿÿÆ'ÆFƒÆ‹MÔ)΋EذÌW‰ÈƒÄ<^_[]ÃU‰åVƒì‹u‰4$èÓýÿÿ‰D$‰4$è5þÿÿƒÄ^]ÃU‰åSWVƒìèX‰Eì»1ö‹ˆV‰Mð‹¸ÿUëƒÆ CSÿ9ú}#‹Eð‹0‹M‰L$‰$èwýÿÿ…ÀuÜ‹Eððé§1Àƒ} ‹}섘‹V9Ê|+ƒÁ2‰V1Àùªªª wkÁ ‰D$‹Eð‰$è+ýÿÿ‰‡V‹E‰$èýÿÿ‰D$‹E‰$è ýÿÿ‹V‰1‹E ‰$è÷üÿÿ‰D$‹E ‰$èèüÿÿ‹V‰D1‹‡VÇD0‰ŸÿU·V‰ðƒÄ^_[]ÃU‰åSWVƒì ‹uƒ¾Ð~61ÿ»‹†Ø‹‰$èüÿÿ‹†Ü‹Dø‰$è{üÿÿƒÃ G;¾Ð|Ñ‹}džЅÿt-‹] ‹†ä…Àt‰$èIüÿÿ‰|$‰$è=üÿÿ‰†ä‰¾àdžèƒÄ ^_[]ÃU‰åWVƒì‹u‹†Ì…Àt‰$èüÿÿ‹†Ø…ÀtBƒ¾Ð~#1ÿ‹†Ü‹Dø‰$èÛûÿÿG;¾Ð|勆؉$èÄûÿÿ‹†Ü‰$è¶ûÿÿ‹†ä…Àt‰$è¤ûÿÿƒÄ^_]é™ûÿÿU‰åSWVƒìÇ$ìè„ûÿÿ‹]‹u ‹}‰$‰EðÇD$ìèhûÿÿ‹Eð…À„²…ö~ƒÇ‹Gü‹‰L$‰$è„ýÿÿƒÇ Nué‹}…ÿthÿÿÿÿ‹uðw½‰$èûÿÿ‰†Ìëdž̅ÿ~EƒÃ‹Cü‹ ‰L$‰$è3ýÿÿ…Àt‹ŽÈQ‰–È‹–̉ŠƒÃ OuÍë ‹uðdž̋E‰D$‹E‰D$‰4$èóýÿÿ‰ðƒÄ^_[]ÃU‰åèX‹€óR]ÃU‰å‹M‹U ]éU‰åWVƒìèX‰Ö‰Ï¸ÎRu*…öt&Ç€ÎR~ƒÇ‹Gü‹‰L$‰$è€üÿÿƒÇ NuéƒÄ^_]ÃU‰åSWVƒì è^¾~R„Ž‹†zR¾rR~L1ÿ1Û‹8‰$èôùÿÿ‹†zR‹D8‰$èâùÿÿ‹†zR‹L8…Ét‰ $‹†¶(ÿ‹†zRƒÇ C;žrR|¸‰$è¯ùÿÿdžzRdžrRdžvRdž~RƒÄ ^_[]ÃU‰åSWVƒìlèX‰E´‹€ý'‰E¬‹‰Eð‹U‹‚Ћu‹}‹M 9È…µƒÇ‰}°ë)ƒÇ A‰ò9Á‰Ö‹–Ì;Šuå‹E؉ò‚è‹uÇEÐ1Éë‰þ‹MÀA‹E´;ˆ½Q<kù ‰}¼‰MÀ‹€ÅQ‰E¸8‰Ẻ÷…ÿte‹‚È9ø‰ÁLωMÄ1Û‹u°ëƒÆ C‹EÈ;]Ä}ª9û}%‹Fü‹‰L$‰$‰×èÛúÿÿ‰ú‹M‰Ï9EÌt‹‚ȉEÈ9Ã}Ä‹ŠÌ‰ø‹}Ì;<™‰Çu²‹M¼‹u¸‹D‹ºè‰}È‹šà‹ºä…Àu2‰ðt‹DMè‰L$ Mì‰L$‰$ÇD$ÇD$èøÿÿ‰M܉L$‹MȉL$‰\$ ‰û‰\$‰$ÇD$ÇD$ÇD$èä÷ÿÿ…À‹U‹u‰÷ˆËþÿÿ‰þ‹}̉}ЋEÜÉ]Ô‹Mà)Á‰ø‰MØë‹EÐ…Àt‰Ã‹‚È1É‹}°éhþÿÿ‹‚è…öt7‰t$‰D$‹E´€o"‰D$ ‰$ÇD$ÿÿÿÿÇD$èh÷ÿÿ¸þÿÿÿéi‰D$‹E´€·"‰D$ ‰$ÇD$ÿÿÿÿÇD$è5÷ÿÿ¸ÿÿÿÿé6‰}Ì‹uÔ‹M؉ð+‚äȉ‚è‰Ð‹Ð‹€Ø…Òtzÿkÿ 98u9t8u 9L8„#‹u‹ŽÔ9Ê|qƒÁ2‰ŽÔ1ÿùªªª ‰òv1ÀëkÉ ‰L$‰$‰Öè®öÿÿ‰ò‹ŠÔ‰‚Øùÿÿÿw!‹‚ÜÁá‰L$‰$‰Öèöÿÿ‰ò‰Ç‹‚؉ºÜ‰Ñ‹‘ЉÎkÊ Á‹E؉AòEÐò‰ð‹°Ð‹¸Ü‹]…Ûtdûÿÿÿw‰$è'öÿÿ‰D÷Ç÷ëÇD÷Ç÷…Û~<‹MÌ‹Aü‹ ‰L$‰$è2øÿÿ…Àt‹ ÷Q‰÷‹T÷‰ŠKuÕëÇD÷Ç÷‹Eÿ€Ð¸üÿÿÿ‹U …Ò‹Mˆº¸üÿÿÿ9‘ÐŽ©k Øé›…ÉxÊ;E ~Å‹E‹ˆÜ‹E ƒ<Át³1Òë‹UÈB;U‹E}£kú ‰UÈT8‰UÌÇ1öë(‰Ã‹‹MÌ‹ ‰L$‰$è|÷ÿÿ‹M‹‰Ü‹TÙ;²tºF‹E ;4Á|ЋE´€H"‰D$ ‹E‰$ÇD$ÿÿÿÿÇD$èúôÿÿ¸ýÿÿÿ‹M¬‹ ;MðuƒÄl^_[]ÃèÞôÿÿU‰å‹E …Àx*‹M9Ð~‰ÐkÀ ‹‘Ø‹D+ä‰è]ÃX  LV‚#*ÿ'‡önUz-H0 HXöØ … ƒ  D ' ö˜ -!ö 1#! 3ö? 9ö® #• û§Z ·NÒ ¾LX ÖPX C I üö#ö#U# Z Œ ë—TX $XXAöJUJ   J B  ö& ,> OöJnUJ ‘\`ö?U`ö‘a—?FUüöÍöà XF= ¦6(Þõ+J ó(,J oFáU?«8ö^K RáD}0ágU?0«q ìgD1„‰K«g]UüK—ÐðK½£K—ª™K—KöK j]DMÆO—ã?N«Ê …›V× ìâ # *Ç — !Æ—"#Ìö##Ó$# ‡Ý% ¹'ð(#ü‚)# É* ìì,•v-#™.#È£‚/#̪0#д1#Ô¿Ä2#Øã÷3#Ü4#àö5#ä 6#è ü$7  !,t]nU@zn}U"üz—‘"ðz‘ S„ÌU Ïå ÏyŠ#ü XdŽÄ" U?Ž«kDŽƒãŽ—@LŽ© ¤ =£Æ‘—¶}ÉÀÆ’ý Ã> Ã> ™$Z‘P#µŠ%"‘°=¥ }¥ñL '#À’&-æ#×#ë' É$€ ‘l$‹ ‘h$– ‘\% ‘P& ¼#¡ .(¬ %' ‘H&2 L&= _#· } ž ¯ ür¶" X U?¶«ïD¶Ü) ý*ã —*? «*? «*ã —*L +,\¢¹,g¢Ä,o£÷,Ƥ—,=¥,}¥,¥,ƒ¥+++,ƒ¥,ư—,ư—+,¥+++++,Ƥ—)˜5*g5Ä*Æ5—*ˆ5*Ó5*Ì5ö*Æ5—*Ì5ö*Ó5*ˆ5*g5Ä+,‘7J ,˜8,¢8O ,ª9U,´6,¼8,´6,¼8,ª9U-¦…+,=†++,=†.·`}ÌUü`—ð`ö Ì ŸÅ ŸÅ| ®Åh&… 2& E-Ên*ðn*ün—*ün—*ðn+,Do,Æp—)ØQ * Q *FQ*Q *FQ* Q /)ì; *; *;@ * ; 0 ? 1# E  *%Rá $> $ > I!I/.: ; ' I? @ 4I: ;  : ; I  4: ; I I I: ; 4I? : ;  < I: ; : ;  I: ; 8 2 1X Y .: ; ' I? @ : ; I 4: ; I 1X Y .: ;' ? @ : ;I4: ;I.: ;' I? @ : ;I4: ;I 4: ;I1X Y1 !I/ !.: ;' I? @ ": ;I #41$41 %1 &1'1UX Y (41 ).: ; ' I *: ; I+ ,4: ; I-.: ; ' ..: ; ' @ /0&1&IŠ[û ./usr/include/securescanner.cutils.hscanner.h_string.h( hX84òO N† Ÿ” RæY Yxž X"q <çó¿ãt‘bŒ p<>f ’A­‹u×^u[u ZKu#„±=Ÿ­¢ Ÿ¸ Še'¬Ju'«•É /lžfjºfŸ×'rf‚ä‚ Áó#<t\ užƒ!lŸ… ³Ÿ…Ÿ­$t1×ÙŸ…±   <8þ}ž„Xƒ uÿ˜K¬ ó uL q ¬ÊL‡ =Û •à}f %ô äÿrfšt ‡~<®eó­!שe(<—ƒŸŸŸóž†  #$É~ÖfŸ®HÖ(õJ)»Ïg tY*JÚ"ü~%J"ð~J  ž/ J=ƒ„º xò/76v/£ ƒ/eg#d„8Á~ÈÀ/‚/ƒ uuL ï_ƒ ¤Ö­ mÖ»%Y …+=8, J` 7Ì Íƒg„>SBW&>V>>P}°°²Pº¼P½½PÁn’Qƒ’R¾ÁRÁ>uP>@SDDSn’R’>uP>@S†Wup”™S¨­SûVCuTCCVCžuTž V¸éuTéîVîuTVuTQÞáPPÞáPPO‰‰‘WFÝVFÏWFÏSáTV&.WÄûWgûSgªVgªW P}R®V}Q®W©®V®ÂWAISÃRÃÉVÉÓRÓãVãýR_R_fWf®R!ðRðüPü uL ; V; M RM T VT z Rz V ‘ R‘ ™ Q™ ¯ V¯  P & uL& & P& K uLK p Qp " uL­»Vé" ÃVì÷V÷ùWùýV&V&QWk…W…PW&.W.OVa¢V¾ ù S¾Wp r W‹ ™ u°™ ª Pª " u°»Q»F uDF p Rp r Qr ® uD® ° P° Ð SÐ Ù uDÙ Þ PÇÉQ<EEHSH" ÷ùWùýV &V&QWk…W…PW&.W.HV!1uL1CWCHP!1uL1CWCHP*_R_fWfR7:Q:" uD™²PâäP¨øS®øWø9S,P ! P“ “ RÃ Õ PÖ Ö V" @ P" V Q\ Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)scanner.c/usr/local/www/dubalu/libs/scss/srcstringscharreprncurrentlong unsigned int__darwin_size_tsize_tPattern_patterns_szintPattern_patterns_bszPattern_patternstokexprpatternreal_pcrepcrePatternPattern_patterns_initializedPyMem_StrndupPyMem_StrdupreprPattern_regexScanner_resetScanner_delScanner_newexcignore_szignoretokens_sztokens_bsztokensregexstringstring_szTokenrestrictionspatterns_szpatternsRestrictioninput_szinputposScannerScanner_initializedScanner_initializeScanner_finalizeScanner_tokenScanner_rewind_Scanner_scanlong intPattern_matchPattern_finalizePattern_initializePattern_setup__inline_memset_chk__inline_memcpy_chk__dest__src__lenstrlencopyreqlenbeginendcwriteoutjselfi__valrestrictions_szbest_tokenp_tokenp_restrictionkmaxskipstart_aterrptrerroffsetovectorp_patternoptionsretfoundresult•™®H\'\r\n\t\x%02xUnimplemented: restriction set changedSyntaxError[@ char %d: Trying to find one of the %d restricted tokens!]SyntaxError[@ char %d: Bad Token!]HSAH  ÿÿÿÿ ÿÿÿÿÿÿÿÿl7GÎÎŽˆÖ¿áï¯ ¯ÿCgû/¾%-…”-ûbgènOuO €Ì>O|׳(WtÈm§¤¹3M=3‚-’(bÜ4³4£á;.ٻ̃Ðbg‘VÌs1H…\c2d@‘­!{OhÙgÏ$4DTdt„”¤´ÄÔäô$4H`p€ °À‡:ØQbzQ¾˜bÊV ‰«$®d4\Orà· ,°auæ¦ìÍO(Ìë}lo ëœAÀ@ÈÖ1SûHSAH ÿÿÿÿHSAH ÿÿÿÿHSAH  ÿÿÿÿÿÿÿÿÿÿÿÿ c •|&½-µà&ï ì½|5û0€ˆ “òÐ[íŸà/.œ|/‚éæãq«ü¬¿Òåø 1DWj‚#$ݹ§ý$•û$Ò$· ìI$ ŒŠìì,Íž OOÌÞëØØQ…ÊÊV ®¦¦Ï˜˜b•æÃÿÿÿÿ| ˆJA„B F†‡ƒJ$A„B D†n­A„B F†‡ƒ$A„B D†?A„B F†‡ƒF›A„B F†‡ƒá†A„B E†‡göA„B F†‡ƒ]A„B nA„B }OA„B E†‡ÌµA„B F†‡ƒ¡A„B F†‡ƒ" 6A„B     ã ¤×(¡¿  Õ  {  N  Ç «¤F)¡” x¤þ(¡ Þ `¢TX¡¢LX¡•¤Œ.¡q¢XX¡Úg¢PX¡Ú]¢LX¡ÚS¢TX¡ÚM C¢LX¡Ú9¢TX¡Ú1¤.¡Ú ¢TX¡Ú ¢TX¡Ú ó¢LX¡Úí¢TX¡ÚÝ¢XX¡Ú»¡¢XX¡Š‘¢XX¡Šyh¢XX¡eOÞ ·” x c X F 8 ! ú ¿³  o 8¢TX¡M2¢LX¡M$¢TX¡M¢TX¡M ÷¢TX¡Mñâ ×¢TX¡MÑ µ¢PX¡M¨¢PX¡M… c¢LX¡MZ¢TX¡M5) ¤HX¡|â — 1¤Ä(¡|(¤Ð(¡|¤Ç(¡|¤Ê(¡| ¤Í(¡|¤H0¡|þ¤H0¡|÷¤H0¡|ï¤H0¡|â¤HX¡|Ò¤HX¡|dX 8  _ [ R N I E @ <   îêÖÒïëâÞ‘FB! ÖÒ¾ZV ½¹•‘zvVRôðÕÑÈ᫆‚`\95ÿúöÑͼª?-–’o ^ KGkóïàÜÍɺ¶§£”}njc_PL=92.üõñêæ×ÓÌÈÀ¼­©¢ž–’ƒxtmib^WSLHA=62+' üõñâÞÖÒËÇÀ¼´°©¥žš’އƒrngcZVOKD@1-&" úöïëäàÙÕÎÊÿ¸´­©™•ŽŠzvokc_XTLHA=62+'  ÿûôðéåÝÙÒÎÇü¸±­¦¢›—Œ…zvok\XIE62#úöçãÔÐÁ½®ª›—ˆ„uqb^OK<8)% ÷óäàÑ;º²®Ÿ›“ˆ„|xqmeaZVNJC?0,%! óïçãÜØÉžº²®§£œ˜‰…uqjf_[TPHD51*&  ¤),¡i)¤,¡i)¤ ,¡i)¤ù+¡i)¤é+¡i) ¤Ù+¡i)¤É+¡i)¤±+¡i)¤+¡i)ü¤+¡i)ø¤}+¡i)ô¤m+¡i)ð¤]+¡i)ì¤M+¡i)è¤=+¡i)ä¤-+¡i)à¤+¡i)ܤ +¡i)ؤý*¡i)Ô¤í*¡i)ФÝ*¡i)̤Í*¡i)Ȥ½*¡i)Ĥ­*¡i)À¤*¡i)¼¤*¡i)¨¤ë-¡,¤¤Ø-¡, ¤Å-¡,œ¤²-¡,˜¤Ÿ-¡,”¤Œ-¡,¤y-¡,Œ¤f-¡,ˆ¤S-¡,„¤@-¡,€¤--¡,ŠyhWF5-¤„dD,ôÔ´”xX<º HXÉ H0Ø}gTX–PXXXyLXX?&JÖá@Ì,nù]ãg»FŒ" RR<nʬðCzœao¯Ž4_PyMem_Strndup_PyMem_Malloc_memcpy_PyMem_Strdup_strlen_reprn___sprintf_chk_repr_Pattern_regex_Pattern_patterns_Pattern_patterns_sz_strcmp_Pattern_patterns_bsz_PyMem_Realloc_Scanner_reset_PyMem_Free_Scanner_del_Scanner_new___bzero_Scanner_initialized_Pattern_patterns_initialized_Scanner_initialize_Scanner_finalize_Scanner_token_pcre_compile_pcre_exec___stack_chk_fail_Scanner_rewind___stack_chk_guard_pcre_free_reprn.current_reprn.strings_Pattern_initializeÏúíþ@ ؼb`˜:__text__TEXTÆ `øAY€__debug_info__DWARFÆ ¸ &ÀDN__debug_abbrev__DWARF~iÞ__debug_aranges__DWARFçG"__debug_macinfo__DWARFçG"__debug_line__DWARFç†G"0G__debug_loc__DWARFmºÍ%8G&__debug_pubtypes__DWARF'-‡4__debug_str__DWARF9-Í™4__debug_ranges__DWARF10f8hP__data__DATA61–8__bss__DATA :(__cstring__TEXT61¥–8__common__DATA¨b__apple_names__DWARFÛ1Ð;9ˆP4__apple_objc__DWARF«4$ <__apple_namespac__DWARFÏ4$/<__apple_types__DWARFó4}S<(R__debug_inlined__DWARFp6²Ð=ØR __compact_unwind__LD"7‚> S__eh_frame__TEXT(8pˆ? h`S8àV0 P + UH‰åAWAVSPI‰÷I‰þ1ÀM…öt/1ÀL‰ÿHÿÇx èH‰Ã1ÀH…ÛtH‰ßL‰öL‰úèH‰ØBÆ8HƒÄ[A^A_]ÃUH‰åSPH‰ûèH‰ßH‰ÆHƒÄ[]éUH‰åAWAVAUATSPI‰ÿM,7¸M9ýv:L‰ùŠ€ú&€ú t€ú t€ú t€úHƒÀë€ú'uðHƒÀëHÿÀHÿÁHÿÎuÉH=(¹(HFÈH‹HÁHù(r HÇüÿÿÿ1ÀL5BÆ0'J\0IÆL%(ë DˆHÿÃIÿÇM9ïƒ÷E¾Aƒø& '.Ç »!Æ»"#Ì##Ó4$# MÝ% 'ð4(#üH)# * ²,•<-#™4.#È£H/#Ъ40#Ø´41#Ü¿Š2#àã½3#è44#ð5#ø 46#€ Â$7 g ,t4” V@z ªVüz»?ðz4bS„ìŸV ðŸ ð”Š!0 7dŽŠŸ V?ŽrZDŽ4 ㎻ LŽ4u Ë Æ‘».}4Q=4À4Æ’1 äY > äY ™"ƒ ‘ !Þ X #K ‘ð~ =¥4¢ }¥4í L 4$ !é m $V Ý ! & ! è ! %8 É"´ ‘H"¿ ‘D"Ê ‘¸#E ‘ $P ¥ !Õ I &à #[ ‘ü~$f  $q ¢ !ë Å l µ Ï ür¶ Æ V?¶rtD¶4—' 1 (ã »(? r(? r(ã »(L 4)*\¢*g¢Š*o£½*Ƥ»*=¥4*}¥4*¥4*ƒ¥4)))*ƒ¥4*ư»*ư»)*¥4))*o£½)))*Ƥ»'˜54(g5Š(Æ5»(ˆ54(Ó54(Ì5(Æ5»(Ì5(Ó54(ˆ54(g5Š)*‘7¦ *˜84*¢8« *ª9y*´64*¼84*´64*¼84*ª9y+¦…)*=†4))*=†4,·`ªìVü`»…ð`4» ¶ì Ãç ÃçØ Óçh$á ñ$ì +Ên(ðn4(ün»(ün»(ðn4)*Do4*Æp»'ØQk ( Q)(FQ4(Qk (FQ4( Q)-'ì;k (;k (;œ ( ;). › /' ¡ 4.%Rá $> $ > I!I/.: ; ' I? @ 4I: ;  : ; I  4: ; I I I: ; 4I? : ;  < I: ; : ;  I: ; 8 2 1X Y .: ; ' I? @ 4: ; I 1X Y .: ;' ? @ : ;I4: ;I.: ;' I? @ 4: ;I 4: ;I1X Y1 !I/  : ; .: ;' I? @ !41"41 #1 $1%1UX Y &41 '.: ; ' I (: ; I) *4: ; I+.: ; ' ,.: ; ' @ -.&/&I‚[û ./usr/include/securescanner.cutils.hscanner.h_string.h ( „‚84äO\° ‘\ Y Yx¬ f>q<Xç/Ìu< hf<’$əɑ–‘M‘ Lg‘‘’Í=ƒŸ$ ‘¸X Âs't‘'ñÍ­¼­l.jä.»ó'rtžää CɃ#€ž2¼YÈYYˆ»“ ¥»[»»$1»½»[¿   )8þ}‚„È‘ ƒ¹Šu< >" © ¬®æ% K‡ Oz æ}X ¿Ê ò¹r‚šX ‡~J/°qŸ(8¥»­ŸŸóž°  $$É~òfƒôHº(ç.)»%Ÿ*=\"ü~$X"ð~º  žô >K­„È x<Ç/*¬®É" ‘$su'r>8Á~Àƒ­<×e[ áÝ‘h¤" m(!%) <¡%WK8, .n 5” ‡ƒgÊUA^ T F_)ASAAPQZUZjSpU_p’T~U_ÄÉRÉ__±±³P¼¾PÁÁPÉE…]É1]ß]”™Q¨­Q  S ^S1^ž£Sß ^ S)^),S 1^ßA^ENUN^SdyUy±_¼\_dvTvvP\^ú\_vP\^kU\k|T| _kyQyð^ˆÀÀÊS *U*¨^pyS®ÒUÒý^®ÏTÏýS®ÍQÍ/]®ÊRÊ/\®ÇXÇ”vH®ÃYÔvT<AP ªU ªTª¶U¶Ó^ª³T³ÓSÍÓSÓã^W_SŸU^ÛUÛ7]7îUî P . vè~. Ï SÏ ñ Pñ 6 vè~6 = P= o vè~o Ÿ RŸ ° U° vè~Ÿ×T×f vä~f ‹ PŸ ¸ T¸ vä~ŸÛQŸ ¦ Q¦  vð~ Q vð~ŸµRµäSä]@S@]]]`S`‡]‡¯YÒ ]Ÿ © S© v˜³µRµÑS  äP êêRb S+@S@]]HDv˜D]SHDv˜D]SPU^±U_±_¾àPÿPÑ=\ØO_2=På = S / P 9 P; ; S Ä U Ä T¸ Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)scanner.c/usr/local/www/dubalu/libs/scss/srcstringscharreprncurrentlong unsigned int__darwin_size_tsize_tPattern_patterns_szintPattern_patterns_bszPattern_patternstokexprpatternreal_pcrepcrePatternPattern_patterns_initializedPyMem_StrndupPyMem_StrdupreprPattern_regexScanner_resetScanner_delScanner_newexcignore_szignoretokens_sztokens_bsztokensregexstringstring_szTokenrestrictionspatterns_szpatternsRestrictioninput_szinputposScannerScanner_initializedScanner_initializeScanner_finalizeScanner_tokenScanner_rewind_Scanner_scanlong intPattern_matchPattern_finalizePattern_initializePattern_setup__inline_memset_chk__inline_memcpy_chk__dest__src__lenstrlencopybeginreqlenendcwriteoutjselfi__valrestrictions_szbest_tokenp_tokenp_restrictionkmaxskipstart_aterrptrerroffsetovectorp_patternoptionsretfoundresult¹¾Û]\'\r\n\t\x%02xUnimplemented: restriction set changedSyntaxError[@ char %d: Trying to find one of the %d restricted tokens!]SyntaxError[@ char %d: Bad Token!]HSAH  ÿÿÿÿ ÿÿÿÿÿÿÿÿl7GÎÎŽˆÖ¿áï¯ ¯ÿCgû/¾%-…”-ûbgènOuO €Ì>O|׳(WtÈm§¤¹3M=3‚-’(bÜ4³4£á;.ٻ̃Ðbg‘VÌs1H…\c2d@‘­!{OhÙgÏ$4DTdt„”¤´ÄÔäô$4H`p€ °À‡>Ørz]¾;˜xʪ ‰Q$Öd%\¤r ·? ,waÓë¦ìZæOtBi}o“ëÀAì@—ÖQSÔHSAH ÿÿÿÿHSAH ÿÿÿÿHSAH  ÿÿÿÿÿÿÿÿÿÿÿÿ c •|&½-µà&ï ì½|5û0€ˆ “òÐ[íŸà/.œ|/‚éæãq«ü¬¿Òåø 1DWj‚'$ݧ1 $•$Ò4$·)²m$g°®ììZ0æµ OOBúiØØßÊʪ Ó¦¦ð˜˜x¹ëäkµ  Ž!®æÑX”   ªB!ŸñÑX 6zRx $¸ÇÿÿÿÿÿÿQA†C FƒŽ$DáÇÿÿÿÿÿÿA†C Bƒ,lØÇÿÿÿÿÿÿÕA†C JƒŒŽ$œ}ÉÿÿÿÿÿÿA†C Bƒ,ÄtÉÿÿÿÿÿÿA†C JƒŒŽ,ôKÊÿÿÿÿÿÿµA†C GƒŒŽ$$ÐÊÿÿÿÿÿÿŽA†C CƒŽ,L6ËÿÿÿÿÿÿæA†C MƒŒŽ$|ìËÿÿÿÿÿÿ A†C $¤ÐËÿÿÿÿÿÿ A†C $̲ËÿÿÿÿÿÿBA†C CƒŽ$ôÌËÿÿÿÿÿÿ³A†C FƒŽ,WÌÿÿÿÿÿÿñA†C PƒŒŽ$LÑÿÿÿÿÿÿ6A†C Œ 0-i 1=[ /-D  - -û ,- --^ --É/-¹ Ÿ/-.4-û3-ˆ-< !¸1=Œ‚xn g+-b YD =+-3 ,+-# 5=mømÛ-Ÿm¦-š~!-8- ,--è.-Ø,-ª+-ž+-+-+-j+-7+-÷-é+-º+-¡+-U N> 2 +- 7-  -þ7-ö ï--ÚË©6-‹„ `)-O7-//-ýÙ»–/-gûîÛl-[7-:2-",-· ¯ ¢ š ‘ ‰ € x O G   óëøðãÛŽ†;3ùñæÞ©¡…ÚÒg_7/ èà¥vnOG:2è๱‰g_C;2*ùäÎ_I®¦ j SKkŸ—|tYQ6. ð è Í Å ª ¢ ‡  d \ Q I . &   ø ð å Ý  º ­ ¥ Š ‚ u m R J ? 7 , $   õ í Ñ É ¾ ¶ ª ¢ † ~ s k ` X ; 3 (     ú ï ç Ü Ô É Á ¶ ® £ ›  ˆ } u X P E = 0 (     å Ý Ò Ê ¿ · ª ¢ —  r j _ W L D 7 / $    üôéáÔÌÁ¹®¦›“ˆ€umbZ?7ùñÖÎû ˜…jbG?$øíåÉÁ¶®“‹€x]UJB' ñéÞÖ»³˜…}bZNF+#õíâÚ¿·¬¤‰umRJ/'åÝÒÊ¿·œ”‰f^SK0( ÷ïäÜÑɾ¶«£˜umbZ?7,$õíâÚÏǼ´¨ …}rj_WLD91óëàØ½µª¢‡tlQI>6 T TTTT T TTTüTüøTøôTôðTðìTìèTèäTäàTàÜTÜØTØÔTÔÐTÐÌTÌÈTÈÄTÄÀTÀ¼T¼¨T¨¤T¤ T œTœ˜T˜”T”TŒTŒˆTˆ„T„€T€ª•€kVA5 àÀ €`@   b¬  :» 91à 61Ê <1Ò ?1Ú B1âªö p1þ ¸1 I1(8ð9g°b–¬b¸by¨bXdðè8&QÌh8º@8Ö H9@ìc:, LÈ9ù”4 9ã®$p9»k9ª Šp:]Ÿx@:REçÀ8<pÝ8ʬðC˜lRŽ4_PyMem_Strndup_PyMem_Malloc_memcpy_PyMem_Strdup_strlen_reprn___sprintf_chk_repr_Pattern_regex_Pattern_patterns_Pattern_patterns_sz_strcmp_Pattern_patterns_bsz_PyMem_Realloc_Scanner_reset_PyMem_Free_Scanner_del_Scanner_new___bzero_Scanner_initialized_Pattern_patterns_initialized_Scanner_initialize_Scanner_finalize_pcre_free_Scanner_token___stack_chk_guard_pcre_compile_pcre_exec___stack_chk_fail_Scanner_rewind_PyMem_Strndup.eh_PyMem_Strdup.eh_reprn.eh_repr.eh_Pattern_regex.eh_Scanner_reset.eh_Scanner_del.eh_Scanner_new.eh_Scanner_initialized.eh_Scanner_initialize.eh_Scanner_finalize.eh_Scanner_token.eh_Scanner_rewind.eh_reprn.current_reprn.stringsL_.str1L_.strL_.str2L_.str3L_.str4_Pattern_initializeL_.str6L_.str7L_.str5EH_frame0_Pattern_initialize.ehpyScss-1.1.5/scss/src/scanner.py0000755000076500000240000003067711700513467017246 0ustar kronuzstaff00000000000000#!/usr/bin/env python ## locate_blocks() needs heavy optimizations... is way too slow right now! ## Any suggestion from python wizards? :-) import re import sys from datetime import datetime import pstats import cProfile from cStringIO import StringIO def profile(fn): def wrapper(*args, **kwargs): profiler = cProfile.Profile() stream = StringIO() profiler.enable() try: res = fn(*args, **kwargs) finally: profiler.disable() stats = pstats.Stats(profiler, stream=stream) stats.sort_stats('time') print >>stream, "" print >>stream, "=" * 100 print >>stream, "Stats:" stats.print_stats() print >>stream, "=" * 100 print >>stream, "Callers:" stats.print_callers() print >>stream, "=" * 100 print >>stream, "Callees:" stats.print_callees() print >>sys.stderr, stream.getvalue() stream.close() return res return wrapper DEBUG = False ################################################################################ # Helpers _units = ['em', 'ex', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'deg', 'rad' 'grad', 'ms', 's', 'hz', 'khz', '%'] PATTERNS = [ ('":"', ':'), ('[ \r\t\n]+', '[ \r\t\n]+'), ('COMMA', ','), ('LPAR', '\\(|\\['), ('RPAR', '\\)|\\]'), ('END', '$'), ('MUL', '[*]'), ('DIV', '/'), ('ADD', '[+]'), ('SUB', '-\\s'), ('SIGN', '-(?![a-zA-Z_])'), ('AND', '(?='), ('LT', '<'), ('GT', '>'), ('STR', "'[^']*'"), ('QSTR', '"[^"]*"'), ('UNITS', '(?= 0 and i < tokens_len: if restrict and self.restrictions[i] and restrict > self.restrictions[i]: raise NotImplementedError("Unimplemented: restriction set changed") if i >= 0 and i < tokens_len: return self.tokens[i] raise NoMoreTokens() def rewind(self, i): tokens_len = len(self.tokens) if i <= tokens_len: token = self.tokens[i] self.tokens = self.tokens[:i] self.restrictions = self.restrictions[:i] self.pos = token[0] class _Scanner_a(Scanner): patterns = None _patterns = PATTERNS def __init__(self, input=None): if hasattr(self, 'setup_patterns'): self.setup_patterns(self._patterns) elif self.patterns is None: self.__class__.patterns = [] for t, p in self._patterns: self.patterns.append((t, re.compile(p))) super(_Scanner_a, self).__init__(None, ['[ \r\t\n]+'], input) ################################################################################ try: from _speedups import Scanner class _Scanner_b(Scanner): patterns = None _patterns = PATTERNS def __init__(self, input=None): if hasattr(self, 'setup_patterns'): self.setup_patterns(self._patterns) elif self.patterns is None: self.__class__.patterns = [] for t, p in self._patterns: self.patterns.append((t, re.compile(p))) super(_Scanner_b, self).__init__(None, ['[ \r\t\n]+'], input) except ImportError: _Scanner_b = None def process_scan(Scanner, level=0, dump=False): ret = '' if dump else None s = Scanner('[(5px - 3) * (5px - 3)]') i = 0 while True: try: s.token(i) i += 1 if dump: ret += '%s\n%s\n' % ('-' * 70, repr(s)) except: break return ret verify = "----------------------------------------------------------------------\n\n (@0) LPAR = '['\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n (@2) NUM = '5'\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n (@8) NUM = '3'\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n (@8) NUM = '3'\n (@9) RPAR = ')'\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n (@8) NUM = '3'\n (@9) RPAR = ')'\n (@11) MUL = '*'\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n (@8) NUM = '3'\n (@9) RPAR = ')'\n (@11) MUL = '*'\n (@13) LPAR = '('\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n (@8) NUM = '3'\n (@9) RPAR = ')'\n (@11) MUL = '*'\n (@13) LPAR = '('\n (@14) NUM = '5'\n----------------------------------------------------------------------\n\n (@1) LPAR = '('\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n (@8) NUM = '3'\n (@9) RPAR = ')'\n (@11) MUL = '*'\n (@13) LPAR = '('\n (@14) NUM = '5'\n (@15) UNITS = 'px'\n----------------------------------------------------------------------\n\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n (@8) NUM = '3'\n (@9) RPAR = ')'\n (@11) MUL = '*'\n (@13) LPAR = '('\n (@14) NUM = '5'\n (@15) UNITS = 'px'\n (@18) SUB = '- '\n----------------------------------------------------------------------\n\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n (@8) NUM = '3'\n (@9) RPAR = ')'\n (@11) MUL = '*'\n (@13) LPAR = '('\n (@14) NUM = '5'\n (@15) UNITS = 'px'\n (@18) SUB = '- '\n (@20) NUM = '3'\n----------------------------------------------------------------------\n\n (@6) SUB = '- '\n (@8) NUM = '3'\n (@9) RPAR = ')'\n (@11) MUL = '*'\n (@13) LPAR = '('\n (@14) NUM = '5'\n (@15) UNITS = 'px'\n (@18) SUB = '- '\n (@20) NUM = '3'\n (@21) RPAR = ')'\n----------------------------------------------------------------------\n\n (@8) NUM = '3'\n (@9) RPAR = ')'\n (@11) MUL = '*'\n (@13) LPAR = '('\n (@14) NUM = '5'\n (@15) UNITS = 'px'\n (@18) SUB = '- '\n (@20) NUM = '3'\n (@21) RPAR = ')'\n (@22) RPAR = ']'\n----------------------------------------------------------------------\n\n (@9) RPAR = ')'\n (@11) MUL = '*'\n (@13) LPAR = '('\n (@14) NUM = '5'\n (@15) UNITS = 'px'\n (@18) SUB = '- '\n (@20) NUM = '3'\n (@21) RPAR = ')'\n (@22) RPAR = ']'\n (@23) END = ''\n" def process_scans(Scanner): for q in xrange(20000): process_scan(Scanner) profiled_process_scans = profile(process_scans) if __name__ == "__main__": for scanner, desc in ( (_Scanner_a, "Pure Python, Full algorithm (_Scanner_a)"), (_Scanner_b, "Builtin C Function, Full algorithm (_Scanner_b)"), ): if scanner: ret = process_scan(scanner, dump=True) # print "This is what %s returned:" % desc # print ret # print repr(ret) assert ret == verify, '\nFrom %s, got:\n%s\nShould be:\n%s' % (desc, ret, verify) start = datetime.now() print >>sys.stderr, "Timing: %s..." % desc, process_scans(scanner) elap = datetime.now() - start elapms = elap.seconds * 1000.0 + elap.microseconds / 1000.0 print >>sys.stderr, "Done! took %06.3fms" % elapms pyScss-1.1.5/scss/src/utils.h0000644000076500000240000000342211676223041016533 0ustar kronuzstaff00000000000000#include #include char * PyMem_Strndup(const char *str, size_t len) { if (str != NULL) { char *copy = PyMem_New(char, len + 1); if (copy != NULL) memcpy(copy, str, len); copy[len] = '\0'; return copy; } return NULL; } char * PyMem_Strdup(const char *str) { return PyMem_Strndup(str, strlen(str)); } char * reprn(char *str, size_t len) { static char strings[10240]; static size_t current = 0; size_t reqlen = 2; char c, *out, *write, *begin = str, *end = str + len; while (begin < end) { c = *begin; if (c == '\'') { reqlen += 2; } else if (c == '\r') { reqlen += 2; } else if (c == '\n') { reqlen += 2; } else if (c == '\t') { reqlen += 2; } else if (c < ' ') { reqlen += 3; } else { reqlen++; } begin++; } if (reqlen > 10240) { reqlen = 10240; } if (current + reqlen > 10240) { current = 0; } begin = str; end = str + len; out = write = strings + current; *write++ = '\''; while (begin < end) { c = *begin; if (c == '\'') { if (write + 5 >= strings + 10240) break; sprintf(write, "\\'"); write += 2; } else if (c == '\r') { if (write + 5 >= strings + 10240) break; sprintf(write, "\\r"); write += 2; } else if (c == '\n') { if (write + 5 >= strings + 10240) break; sprintf(write, "\\n"); write += 2; } else if (c == '\t') { if (write + 5 >= strings + 10240) break; sprintf(write, "\\t"); write += 2; } else if (c < ' ') { if (write + 6 >= strings + 10240) break; sprintf(write, "\\x%02x", c); write += 3; } else { if (write + 4 >= strings + 10240) break; *write++ = c; } begin++; } *write++ = '\''; *write++ = '\0'; current += (size_t)(write - out); return out; } char * repr(char *str) { return reprn(str, strlen(str)); } pyScss-1.1.5/scss/tests.rst0000644000076500000240000010716312106741154016335 0ustar kronuzstaff00000000000000SCSS TESTS ========== INITIALIZATION -------------- >>> from scss import Scss >>> css = Scss() VARIABLES --------- http://xcss.antpaw.org/docs/syntax/variables >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... @variables { ... $path = ../img/tmpl1/png; ... $color1 = #FF00FF; ... $border = border-top: 1px solid $color1; ... } ... .selector { ... background-image: url($path/head_bg.png); ... background-color: $color1; ... $border; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .selector { background-image: url(../img/tmpl1/png/head_bg.png); background-color: #f0f; border-top: 1px solid #f0f; } NESTING CHILD OBJECTS --------------------- http://xcss.antpaw.org/docs/syntax/children >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .selector { ... a { ... display: block; ... } ... strong { ... color: blue; ... } ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .selector a { display: block; } .selector strong { color: #00f; } >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .selector { ... self { ... margin: 20px; ... } ... a { ... display: block; ... } ... strong { ... color: blue; ... } ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .selector { margin: 20px; } .selector a { display: block; } .selector strong { color: #00f; } >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .selector { ... self { ... margin: 20px; ... } ... a { ... display: block; ... } ... dl { ... dt { ... color: red; ... } ... dd { ... self { ... color: gray; ... } ... span { ... text-decoration: underline; ... } ... } ... } ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .selector { margin: 20px; } .selector a { display: block; } .selector dl dt { color: red; } .selector dl dd { color: gray; } .selector dl dd span { text-decoration: underline; } EXTENDING OBJECTS ----------------- http://xcss.antpaw.org/docs/syntax/extends >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .basicClass { ... padding: 20px; ... background-color: #FF0000; ... } ... .specialClass extends .basicClass {} ... ''') #doctest: +NORMALIZE_WHITESPACE .basicClass, .specialClass { padding: 20px; background-color: red; } >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .basicClass { ... padding: 20px; ... background-color: #FF0000; ... } ... .specialClass extends .basicClass { ... padding: 10px; ... font-size: 14px; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .basicClass, .specialClass { padding: 20px; background-color: red; } .specialClass { padding: 10px; font-size: 14px; } >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .specialClass extends .basicClass { ... padding: 10px; ... font-size: 14px; ... } ... .specialLink extends .basicClass a {} ... .basicClass { ... self { ... padding: 20px; ... background-color: #FF0000; ... } ... a { ... text-decoration: none; ... } ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .basicClass, .specialClass { padding: 20px; background-color: red; } .basicClass a, .specialClass a, .specialLink { text-decoration: none; } .specialClass { padding: 10px; font-size: 14px; } >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .basicList { ... li { ... padding: 5px 10px; ... border-bottom: 1px solid #000000; ... } ... dd { ... margin: 4px; ... } ... span { ... display: inline-block; ... } ... } ... .roundBox { ... some: props; ... } ... .specialClass extends .basicList & .roundBox {} ... ''') #doctest: +NORMALIZE_WHITESPACE .basicList li, .specialClass li { padding: 5px 10px; border-bottom: 1px solid #000; } .basicList dd, .specialClass dd { margin: 4px; } .basicList span, .specialClass span { display: inline-block; } .roundBox, .specialClass { some: props; } >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .basicList { ... li { ... padding: 5px 10px; ... border-bottom: 1px solid #000000; ... } ... dd { ... margin: 4px; ... } ... span { ... display: inline-block; ... } ... } ... .specialClass { ... dt extends .basicList li {} ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .basicList li, .specialClass dt { padding: 5px 10px; border-bottom: 1px solid #000; } .basicList dd { margin: 4px; } .basicList span { display: inline-block; } MATH OPERATIONS --------------- http://xcss.antpaw.org/docs/syntax/math >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... @variables { ... $color = #FFF555; ... } ... .selector { ... padding: [5px * 2]; ... color: [#ccc * 2]; ... // lets assume $color is '#FFF555' ... background-color: [$color - #222 + #101010]; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .selector { padding: 10px; color: #fff; background-color: #ede343; } >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .selector { ... padding: [(5px - 3) * (5px - 3)]; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .selector { padding: 4px; } >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .selector { ... padding: [5em - 3em + 5px]px; ... margin: [20 - 10] [30% - 10]; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .selector { padding: 31px; margin: 10 20%; } SASS NESTING COMPATIBILITY -------------------------- http://sass-lang.com/tutorial.html >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... /* style.scss */ ... #navbar { ... width: 80%; ... height: 23px; ... ... ul { list-style-type: none; } ... li { ... float: left; ... a { font-weight: bold; } ... } ... } ... ''') #doctest: +NORMALIZE_WHITESPACE #navbar { width: 80%; height: 23px; } #navbar ul { list-style-type: none; } #navbar li { float: left; } #navbar li a { font-weight: bold; } >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... /* style.scss */ ... .fakeshadow { ... border: { ... style: solid; ... left: { ... width: 4px; ... color: #888; ... } ... right: { ... width: 2px; ... color: #ccc; ... } ... } ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .fakeshadow { border-style: solid; border-left-width: 4px; border-left-color: #888; border-right-width: 2px; border-right-color: #ccc; } >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... /* style.scss */ ... a { ... color: #ce4dd6; ... &:hover { color: #ffb3ff; } ... &:visited { color: #c458cb; } ... } ... ''') #doctest: +NORMALIZE_WHITESPACE a { color: #ce4dd6; } a:hover { color: #ffb3ff; } a:visited { color: #c458cb; } SASS VARIABLES COMPATIBILITY ---------------------------- http://sass-lang.com/tutorial.html >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... /* style.scss */ ... $main-color: #ce4dd6; ... $style: solid; ... ... #navbar { ... border-bottom: { ... color: $main-color; ... style: $style; ... } ... } ... ... a { ... color: $main-color; ... &:hover { border-bottom: $style 1px; } ... } ... ''') #doctest: +NORMALIZE_WHITESPACE #navbar { border-bottom-color: #ce4dd6; border-bottom-style: solid; } a { color: #ce4dd6; } a:hover { border-bottom: solid 1px; } SASS INTERPOLATION COMPATIBILITY -------------------------------- http://sass-lang.com/tutorial.html >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... /* style.scss */ ... $side: top; ... $radius: 10px; ... ... .rounded-#{$side} { ... border-#{$side}-radius: $radius; ... -moz-border-radius-#{$side}: $radius; ... -webkit-border-#{$side}-radius: $radius; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .rounded-top { border-top-radius: 10px; -moz-border-radius-top: 10px; -webkit-border-top-radius: 10px; } SASS MIXINS COMPATIBILITY ------------------------- http://sass-lang.com/tutorial.html >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... /* style.scss */ ... ... @mixin rounded-top { ... $side: top; ... $radius: 10px; ... ... border-#{$side}-radius: $radius; ... -moz-border-radius-#{$side}: $radius; ... -webkit-border-#{$side}-radius: $radius; ... } ... ... #navbar li { @include rounded-top; } ... #footer { @include rounded-top; } ... ''') #doctest: +NORMALIZE_WHITESPACE #navbar li { border-top-radius: 10px; -moz-border-radius-top: 10px; -webkit-border-top-radius: 10px; } #footer { border-top-radius: 10px; -moz-border-radius-top: 10px; -webkit-border-top-radius: 10px; } >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... /* style.scss */ ... ... @mixin rounded($side, $radius: 10px) { ... border-#{$side}-radius: $radius; ... -moz-border-radius-#{$side}: $radius; ... -webkit-border-#{$side}-radius: $radius; ... } ... ... #navbar li { @include rounded(top); } ... #footer { @include rounded(top, 5px); } ... #sidebar { @include rounded(left, 8px); } ... ''') #doctest: +NORMALIZE_WHITESPACE #navbar li { border-top-radius: 10px; -moz-border-radius-top: 10px; -webkit-border-top-radius: 10px; } #footer { border-top-radius: 5px; -moz-border-radius-top: 5px; -webkit-border-top-radius: 5px; } #sidebar { border-left-radius: 8px; -moz-border-radius-left: 8px; -webkit-border-left-radius: 8px; } Support for ``@content`` >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... @mixin iphone { ... @media only screen and (max-width: 480px) { ... @content; ... } ... } ... ... @include iphone { ... body { color: red } ... } ... ''') #doctest: +NORMALIZE_WHITESPACE @media only screen and (max-width: 480px) { body { color: red; } } SASS EXTEND COMPATIBILITY ------------------------- http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#extend >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .error { ... border: 1px #f00; ... background-color: #fdd; ... } ... .error.intrusion { ... background-image: url("/image/hacked.png"); ... } ... .seriousError { ... @extend .error; ... border-width: 3px; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .error, .seriousError { border: 1px red; background-color: #fdd; } .error.intrusion, .seriousError.intrusion { background-image: url("/image/hacked.png"); } .seriousError { border-width: 3px; } ### Multiple Extends >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .error { ... border: 1px #f00; ... background-color: #fdd; ... } ... .attention { ... font-size: 3em; ... background-color: #ff0; ... } ... .seriousError { ... @extend .error, .attention; ... border-width: 3px; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .error, .seriousError { border: 1px red; background-color: #fdd; } .attention, .seriousError { font-size: 3em; background-color: #ff0; } .seriousError { border-width: 3px; } Multiple Extends >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .bad { ... color: red !important; ... } ... .error { ... border: 1px #f00; ... background-color: #fdd; ... } ... .attention { ... font-size: 3em; ... background-color: #ff0; ... } ... .seriousError { ... @extend .error, .attention; ... @extend .bad; ... border-width: 3px; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .bad, .seriousError { color: red !important; } .error, .seriousError { border: 1px red; background-color: #fdd; } .attention, .seriousError { font-size: 3em; background-color: #ff0; } .seriousError { border-width: 3px; } Placeholder Selectors: ``%foo`` >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... // This ruleset won't be rendered on its own. ... #context a%extreme { ... color: blue; ... font-weight: bold; ... font-size: 2em; ... } ... .notice { @extend %extreme; } ... ''') #doctest: +NORMALIZE_WHITESPACE #context a.notice { color: #00f; font-weight: bold; font-size: 2em; } FROM THE FORUM -------------- http://groups.google.com/group/xcss/browse_thread/thread/6989243973938362# >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... body { ... _width: expression(document.body.clientWidth > 1440? "1440px" : "auto"); ... } ... ''') #doctest: +NORMALIZE_WHITESPACE body { _width: expression(document.body.clientWidth > 1440? "1440px" : "auto"); } http://groups.google.com/group/xcss/browse_thread/thread/2d27ddec3c15c385# >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... @variables { ... $ie6 = *html; ... $ie7 = *:first-child+html; ... } ... $ie6 { ... .a { color:white; } ... .b { color:black; } ... } ... $ie7 { ... .a { color:white; } ... .b { color:black; } ... } ... ''') #doctest: +NORMALIZE_WHITESPACE *html .a { color: #fff; } *html .b { color: #000; } *:first-child+html .a { color: #fff; } *:first-child+html .b { color: #000; } http://groups.google.com/group/xcss/browse_thread/thread/04faafb4ef178984# >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .basicClass { ... padding: 20px; ... background-color: #FF0000; ... } ... .specialClass extends .basicClass { ... padding: 10px; ... font-size: 14px; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .basicClass, .specialClass { padding: 20px; background-color: red; } .specialClass { padding: 10px; font-size: 14px; } ERRORS ------ http://groups.google.com/group/xcss/browse_thread/thread/5f4f3af046883c3b# >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .some-selector { some:prop; } ... .some-selector-more { some:proop; } ... .parent { ... self extends .some-selector { ... height: auto ... } ... .children { ... self extends .some-selector-more { ... height: autoo ... } ... } ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .parent, .some-selector { some: prop; } .parent .children, .some-selector-more { some: proop; } .parent { height: auto; } .parent .children { height: autoo; } http://groups.google.com/group/xcss/browse_thread/thread/540f8ad0771c053b# >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .noticeBox { ... self { ... background-color:red; ... } ... span, p { ... some: props ... } ... } ... .errorBox extends .noticeBox {} ... ''') #doctest: +NORMALIZE_WHITESPACE .errorBox, .noticeBox { background-color: red; } .errorBox p, .errorBox span, .noticeBox p, .noticeBox span { some: props; } http://groups.google.com/group/xcss/browse_thread/thread/b5757c24586c1519# >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .mod { ... self { ... margin: 10px; ... } ... h1 { ... font-size:40px; ... } ... } ... .cleanBox extends .mod { ... h1 { ... font-size:60px; ... } ... } ... .cleanBoxExtended extends .cleanBox {} ... .articleBox extends .cleanBox {} ... ''') #doctest: +NORMALIZE_WHITESPACE .articleBox, .cleanBox, .cleanBoxExtended, .mod { margin: 10px; } .articleBox h1, .cleanBox h1, .cleanBoxExtended h1, .mod h1 { font-size: 40px; } .articleBox h1, .cleanBox h1, .cleanBoxExtended h1 { font-size: 60px; } TESTS ----- >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... @function percent-width( ... $t, ... $c ... ) { ... $perc: ($t / $c) * 100%; ... @return $perc; ... } ... ... a { ... width: percent-width(12, 80); ... } ... ''') #doctest: +NORMALIZE_WHITESPACE a { width: 15%; } http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... a { ... $color: rgba(0.872536*255, 0.48481984*255, 0.375464*255, 1); ... color: $color; ... color: hsl(13.2, 0.661, 0.624); ... color-hue: hue($color); // 60deg ... color-saturation: saturation($color); // 60% ... color-lightness: lightness($color); // 50% ... } ... ''') #doctest: +NORMALIZE_WHITESPACE a { color: rgb(87.254%, 48.482%, 37.546%); color: hsl(13.2, 66.1%, 62.4%); color-hue: 13.2deg; color-saturation: 66.1%; color-lightness: 62.4%; } >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .functions { ... opacify1: opacify(rgba(0, 0, 0, 0.5), 0.1); // rgba(0, 0, 0, 0.6) ... opacify2: opacify(rgba(0, 0, 17, 0.8), 0.2); // #001 ... ... transparentize1: transparentize(rgba(0, 0, 0, 0.5), 0.1); // rgba(0, 0, 0, 0.4) ... transparentize2: transparentize(rgba(0, 0, 0, 0.8), 0.2); // rgba(0, 0, 0, 0.6) ... ... lighten1: lighten(hsl(0, 0%, 0%), 30%); // hsl(0, 0, 30) ... lighten2: lighten(#800, 20%); // #e00 ... ... darken1: darken(hsl(25, 100%, 80%), 30%); // hsl(25deg, 100%, 50%) ... darken2: darken(#800, 20%); // #200 ... ... saturate1: saturate(hsl(120, 30%, 90%), 20%); // hsl(120deg, 50%, 90%) ... saturate2: saturate(#855, 20%); // #9e3f3f ... ... desaturate1: desaturate(hsl(120, 30%, 90%), 20%); // hsl(120deg, 10%, 90%) ... desaturate2: desaturate(#855, 20%); // #726b6b ... ... adjust1: adjust-hue(hsl(120, 30%, 90%), 60deg); // hsl(180deg, 30%, 90%) ... adjust2: adjust-hue(hsl(120, 30%, 90%), -60deg); // hsl(60deg, 30%, 90%) ... adjust3: adjust-hue(#811, 45deg); // #886a11 ... ... mix1: mix(#f00, #00f, 50%); // purple ... mix2: mix(#f00, #00f, 25%); // #4000bf ... mix3: mix(rgba(255, 0, 0, 0.5), #00f, 50%); // rgba(64, 0, 191, 0.75) ... ... percentage1: percentage(100px / 50px); // 200% ... ... round1: round(10.4px); // 10px ... round2: round(10.6px); // 11px ... ... ceil1: ceil(10.4px); // 11px ... ceil2: ceil(10.6px); // 11px ... ... floor1: floor(10.4px); // 10px ... floor2: floor(10.6px); // 10px ... ... abs1: abs(10px); // 10px ... abs2: abs(-10px); // 10px ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .functions { opacify1: rgba(0, 0, 0, 0.6); opacify2: #001; transparentize1: rgba(0, 0, 0, 0.4); transparentize2: rgba(0, 0, 0, 0.6); lighten1: hsl(0, 0%, 30%); lighten2: #e00; darken1: hsl(25, 100%, 50%); darken2: #200; saturate1: hsl(120, 50%, 90%); saturate2: #9e3f3f; desaturate1: hsl(120, 10%, 90%); desaturate2: #726b6b; adjust1: hsl(180, 30%, 90%); adjust2: hsl(60, 30%, 90%); adjust3: #886a11; mix1: purple; mix2: #4000bf; mix3: rgba(64, 0, 191, 0.75); percentage1: 200%; round1: 10px; round2: 11px; ceil1: 11px; ceil2: 11px; floor1: 10px; floor2: 10px; abs1: 10px; abs2: 10px; } >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .coloredClass { ... $mycolor: green; ... padding: 20px; ... background-color: $mycolor; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .coloredClass { padding: 20px; background-color: green; } >>> css._scss_files = {} >>> css._scss_files['first.css'] = ''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .specialClass extends .basicClass { ... padding: 10px; ... font-size: 14px; ... } ... ''' >>> css._scss_files['second.css'] = ''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... .basicClass { ... padding: 20px; ... background-color: #FF0000; ... } ... ''' >>> print css.compile() #doctest: +NORMALIZE_WHITESPACE .basicClass, .specialClass { padding: 20px; background-color: red; } .specialClass { padding: 10px; font-size: 14px; } >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... a, button { ... color: blue; ... &:hover, .some & { ... text-decoration: underline; ... } ... } ... ''') #doctest: +NORMALIZE_WHITESPACE a, button { color: #00f; } .some a, .some button, a:hover, button:hover { text-decoration: underline; } All styles defined for a:hover are also applied to .hoverlink: >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... a:hover { text-decoration: underline } ... .hoverlink { @extend a:hover } ... ''') #doctest: +NORMALIZE_WHITESPACE .hoverlink, a:hover { text-decoration: underline; } http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... #fake-links .link {@extend a} ... ... a { ... color: blue; ... &:hover {text-decoration: underline} ... } ... ''') #doctest: +NORMALIZE_WHITESPACE #fake-links .link, a { color: #00f; } #fake-links .link:hover, a:hover { text-decoration: underline; } >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... @each $animal in puma, sea-slug, egret, salamander { ... .#{$animal}-icon { ... background-image: url('/images/#{$animal}.png'); ... } ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .puma-icon { background-image: url(/images/puma.png); } .sea-slug-icon { background-image: url(/images/sea-slug.png); } .egret-icon { background-image: url(/images/egret.png); } .salamander-icon { background-image: url(/images/salamander.png); } TESTS FOR REPORTED ISSUES ------------------------- ### Issue #2 test >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... #{enumerate(".pull", 1, 24)} { ... display: inline; ... float: left; ... position: relative; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .pull-1, .pull-10, .pull-11, .pull-12, .pull-13, .pull-14, .pull-15, .pull-16, .pull-17, .pull-18, .pull-19, .pull-2, .pull-20, .pull-21, .pull-22, .pull-23, .pull-24, .pull-3, .pull-4, .pull-5, .pull-6, .pull-7, .pull-8, .pull-9 { display: inline; float: left; position: relative; } ### Issue #4 test >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... $width: 150px; ... @mixin foo($width) { ... width: $width; ... } ... $other_width: 100px; ... .foo { ... @include foo($other_width); ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .foo { width: 100px; } ### Issue #5 test >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... $width: 1px; ... foo { ... border: $width solid red; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE foo { border: 1px solid red; } ### Issue #6 test >>> print css.compile(''' ... @option compress:no, short_colors:yes, reverse_colors:yes; ... $type: monster; ... p { ... @if $type == ocean { ... color: blue; ... } @else if $type == matador { ... color: red; ... } @else if $type == monster { ... color: green; ... } @else { ... color: black; ... } ... } ... ''') #doctest: +NORMALIZE_WHITESPACE p { color: green; } ### Issue #7 test >>> print css.compile(''' ... @option compress: no, short_colors: no; ... a.button:hover { ... color: #000000; ... } ... button:hover { ... @extend a.button:hover; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE a.button:hover, button:hover { color: #000000; } ### Issue #10 test >>> print css.compile(''' ... @option compress: no, short_colors: no; ... .yellow { ... color: yelow; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE .yellow { color: yelow; } ### Issue #21 test >>> print css.compile(''' ... @option compress:no, short_colors: no; ... h2 { ... background: green; ... @media screen{ ... background:blue; ... } ... } ... h1 { ... background:yellow; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE h2 { background: #008000; } @media screen { h2 { background: #0000ff; } } h1 { background: #ffff00; } ### Issue #32 test >>> print css.compile(''' ... @option compress:no, short_colors: no; ... @media (max-width:1024px) { ... .wrap { ... padding: 10px 0; ... } ... } ... ''') #doctest: +NORMALIZE_WHITESPACE @media (max-width:1024px) { .wrap { padding: 10px 0; } } ### Issue #40 test >>> print css.compile(''' ... @option compress:no, short_colors: no; ... a { ... background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwA..."); ... } ... ''') #doctest: +NORMALIZE_WHITESPACE a { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwA..."); } ### Issue #52 test >>> print css.compile(''' ... @option compress:no; ... h1 { ... background: url(//example.com/image.png); ... } ... ''') #doctest: +NORMALIZE_WHITESPACE h1 { background: url(//example.com/image.png); } ### Strings interpolation >>> print css.compile(''' ... @option compress:no, short_colors: no; ... a { ... $a: 'a'; ... $b: 'b'; ... $c: 'c'; ... $x: ''; ... A: $a$b$x$c; ... B: '$a$b$x$c'; ... C: "$a$b$x$c"; ... D: #{$a}#{$b}#{$x}#{$c}; ... E: '#{$a}#{$b}#{$x}#{$c}'; ... F: "#{$a}#{$b}#{$x}#{$c}"; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE a { A: a b c; B: $a$b$x$c; C: "$a$b$x$c"; D: abc; E: abc; F: "abc"; } ### Strings interpolation >>> print css.compile(''' ... @option compress:no, short_colors: no; ... a { ... @each $a in '', '_a' { ... @each $b in '', '_b' { ... @each $c in '', '_c' { ... A: X#{$a}#{$b}#{$c}; ... } ... } ... } ... } ... ''') #doctest: +NORMALIZE_WHITESPACE a { A: X; A: X_c; A: X_b; A: X_b_c; A: X_a; A: X_a_c; A: X_a_b; A: X_a_b_c; } ### Compass excerpt >>> print css.compile(''' ... @option compress:no, short_colors: no; ... ... $experimental-support-for-mozilla : true !default; ... $experimental-support-for-webkit : true !default; ... $experimental-support-for-opera : true !default; ... $experimental-support-for-microsoft : true !default; ... $experimental-support-for-khtml : false !default; ... ... @mixin experimental($property, $value, ... $moz : $experimental-support-for-mozilla, ... $webkit : $experimental-support-for-webkit, ... $o : $experimental-support-for-opera, ... $ms : $experimental-support-for-microsoft, ... $khtml : $experimental-support-for-khtml, ... $official : true ... ) { ... @if $webkit and $experimental-support-for-webkit { -webkit-#{$property} : $value; } ... @if $khtml and $experimental-support-for-khtml { -khtml-#{$property} : $value; } ... @if $moz and $experimental-support-for-mozilla { -moz-#{$property} : $value; } ... @if $ms and $experimental-support-for-microsoft { -ms-#{$property} : $value; } ... @if $o and $experimental-support-for-opera { -o-#{$property} : $value; } ... @if $official { #{$property} : $value; } ... } ... ... $default-box-shadow-color: #333333 !default; ... $default-box-shadow-h-offset: 0px !default; ... $default-box-shadow-v-offset: 0px !default; ... $default-box-shadow-blur: 5px !default; ... $default-box-shadow-spread : false !default; ... $default-box-shadow-inset : false !default; ... ... @mixin box-shadow( ... $shadow-1 : default, ... $shadow-2 : false, ... $shadow-3 : false, ... $shadow-4 : false, ... $shadow-5 : false, ... $shadow-6 : false, ... $shadow-7 : false, ... $shadow-8 : false, ... $shadow-9 : false, ... $shadow-10: false ... ) { ... @if $shadow-1 == default { ... $shadow-1 : -compass-space-list(compact(if($default-box-shadow-inset, inset, false), $default-box-shadow-h-offset, $default-box-shadow-v-offset, $default-box-shadow-blur, $default-box-shadow-spread, $default-box-shadow-color)); ... } ... $shadow : compact($shadow-1, $shadow-2, $shadow-3, $shadow-4, $shadow-5, $shadow-6, $shadow-7, $shadow-8, $shadow-9, $shadow-10); ... @include experimental(box-shadow, $shadow, ... -moz, -webkit, not -o, not -ms, not -khtml, official ... ); ... } ... ... a { ... $drop-shadow-color: red; ... $drop-shadow-blur: 4px; ... $inner-shadow-color: rgba(0, 0, 0, 0.5); ... $inner-shadow-blur: 40px !default; ... $offset-x: 0; ... $offset-y: -1px; ... +box-shadow: $drop-shadow-color $offset-x $offset-y $drop-shadow-blur 0, $inner-shadow-color 0 0 $inner-shadow-blur inset; ... } ... ''') #doctest: +NORMALIZE_WHITESPACE a { -webkit-box-shadow: #ff0000 0 -1px 4px 0, rgba(0, 0, 0, 0.5) 0 0 40px inset; -moz-box-shadow: #ff0000 0 -1px 4px 0, rgba(0, 0, 0, 0.5) 0 0 40px inset; box-shadow: #ff0000 0 -1px 4px 0, rgba(0, 0, 0, 0.5) 0 0 40px inset; } UNSUPPORTED ----------- >>> UNSUPPORTED = """ ... ADVANCED STUFF, NOT SUPPORTED (FROM SASS): ... -------------------------------------------------------------------------------- ... >>> print css.compile(''' ... ... @option compress:no, short_colors:yes, reverse_colors:yes; ... ... .mod { ... ... margin: 10px; ... ... } ... ... .mod h1 { ... ... font-size: 40px; ... ... } ... ... .cleanBox h1 extends .mod { ... ... font-size: 60px; ... ... } ... ... ''') #doctest: +NORMALIZE_WHITESPACE ... .cleanBox h1, ... .mod { ... margin: 10px; ... } ... .cleanBox h1, ... .mod h1 { ... font-size: 40px; ... } ... .cleanBox h1 { ... font-size: 60px; ... } ... ... http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html ... ... Any rule that uses a:hover will also work for .hoverlink, even if they have other selectors as well ... >>> print css.compile(''' ... ... @option compress:no, short_colors:yes, reverse_colors:yes; ... ... .comment a.user:hover { font-weight: bold } ... ... .hoverlink { @extend a:hover } ... ... ''') #doctest: +NORMALIZE_WHITESPACE ... .comment a.user:hover, ... .comment .hoverlink.user { ... font-weight: bold; ... } ... ... ... Sometimes a selector sequence extends another selector that appears in another ... sequence. In this case, the two sequences need to be merged. ... While it would technically be possible to generate all selectors that could ... possibly match either sequence, this would make the stylesheet far too large. ... The simple example above, for instance, would require ten selectors. Instead, ... Sass generates only selectors that are likely to be useful. ... >>> print css.compile(''' ... ... @option compress:no, short_colors:yes, reverse_colors:yes; ... ... #admin .tabbar a { font-weight: bold } ... ... #demo .overview .fakelink { @extend a } ... ... ''') #doctest: +NORMALIZE_WHITESPACE ... #admin .tabbar a, ... #admin .tabbar #demo .overview .fakelink, ... #demo .overview #admin .tabbar .fakelink { ... font-weight: bold; ... } ... ... -------------------------------------------------------------------------------- ... """ pyScss-1.1.5/scss/tool.py0000644000076500000240000003475012106741154015771 0ustar kronuzstaff00000000000000#!/usr/bin/env python from __future__ import absolute_import import logging import os import re import sys from collections import deque from scss import config from scss import Scss, log, spawn_rule, to_str, profiling from scss import _prop_split_re from scss.scss_meta import BUILD_INFO log.setLevel(logging.INFO) def main(): logging.basicConfig(format="%(levelname)s: %(message)s") from optparse import OptionGroup, OptionParser, SUPPRESS_HELP parser = OptionParser(usage="Usage: %prog [options] [file]", description="Converts Scss files to CSS.", add_help_option=False) parser.add_option("-i", "--interactive", action="store_true", help="Run an interactive Scss shell") parser.add_option("-w", "--watch", metavar="DIR", help="Watch the files in DIR, and recompile when they change") parser.add_option("-r", "--recursive", action="store_true", help="Also watch directories inside of the watch directory") parser.add_option("-o", "--output", metavar="PATH", help="Write output to PATH (a directory if using watch, a file otherwise)") parser.add_option("-s", "--suffix", metavar="STRING", help="If using watch, a suffix added to the output filename (i.e. filename.STRING.css)") parser.add_option("--time", action="store_true", help="Display compliation times") parser.add_option("--debug-info", action="store_true", help="Turns on scss's debuging information") parser.add_option("--no-debug-info", action="store_false", dest="debug_info", default=False, help="Turns off scss's debuging information") parser.add_option("-t", "--test", action="store_true", help=SUPPRESS_HELP) parser.add_option("-C", "--no-compress", action="store_false", dest="compress", default=True, help="Don't minify outputted CSS") parser.add_option("-?", action="help", help=SUPPRESS_HELP) parser.add_option("-h", "--help", action="help", help="Show this message and exit") parser.add_option("-v", "--version", action="store_true", help="Print version and exit") paths_group = OptionGroup(parser, "Resource Paths") paths_group.add_option("-I", "--load-path", metavar="PATH", action="append", dest="load_paths", help="Add a scss import path, may be given multiple times") paths_group.add_option("-S", "--static-root", metavar="PATH", dest="static_root", help="Static root path (Where images and static resources are located)") paths_group.add_option("-A", "--assets-root", metavar="PATH", dest="assets_root", help="Assets root path (Sprite images will be created here)") paths_group.add_option("-a", "--assets-url", metavar="URL", dest="assets_url", help="URL to reach the files in your assets_root") parser.add_option_group(paths_group) (options, args) = parser.parse_args() # General runtime configuration config.VERBOSITY = 0 if options.time: config.VERBOSITY = 2 if options.static_root is not None: config.STATIC_ROOT = options.static_root if options.assets_root is not None: config.ASSETS_ROOT = options.assets_root if options.load_paths is not None: # TODO: Convert global config.LOAD_PATHS to a list. Use it directly. # Doing the above will break backwards compatibility! if hasattr(config.LOAD_PATHS, 'split'): load_path_list = [p.strip() for p in config.LOAD_PATHS.split(',')] else: load_path_list = list(config.LOAD_PATHS) for path_param in options.load_paths: for p in path_param.replace(os.pathsep, ',').replace(';', ',').split(','): p = p.strip() if p and p not in load_path_list: load_path_list.append(p) # TODO: Remove this once global config.LOAD_PATHS is a list. if hasattr(config.LOAD_PATHS, 'split'): config.LOAD_PATHS = ','.join(load_path_list) else: config.LOAD_PATHS = load_path_list if options.assets_url is not None: config.ASSETS_URL = options.assets_url # Execution modes if options.test: import doctest doctest.testfile('tests.rst') elif options.version: print BUILD_INFO elif options.interactive: from pprint import pprint try: import atexit import readline histfile = os.path.expanduser('~/.scss-history') try: readline.read_history_file(histfile) except IOError: pass atexit.register(readline.write_history_file, histfile) except ImportError: pass css = Scss() context = css.scss_vars options = css.scss_opts rule = spawn_rule(context=context, options=options) print "Welcome to %s interactive shell" % BUILD_INFO while True: try: s = raw_input('>>> ').strip() except EOFError: print break except KeyboardInterrupt: print break if s in ('exit', 'quit'): break for s in s.split(';'): s = css.load_string(s.strip()) if not s: continue elif s.startswith('@'): properties = [] children = deque() spawn_rule(fileid='', context=context, options=options, properties=properties) code, name = (s.split(None, 1) + [''])[:2] if code == '@option': css._settle_options(rule, [''], set(), children, None, None, s, None, code, name) continue elif code == '@import': css._do_import(rule, [''], set(), children, None, None, s, None, code, name) continue elif code == '@include': final_cont = '' css._do_include(rule, [''], set(), children, None, None, s, None, code, name) code = css._print_properties(properties).rstrip('\n') if code: final_cont += code if children: css.children.extendleft(children) css.parse_children() code = css._create_css(css.rules).rstrip('\n') if code: final_cont += code final_cont = css.post_process(final_cont) print final_cont continue elif s == 'ls' or s.startswith('show(') or s.startswith('show ') or s.startswith('ls(') or s.startswith('ls '): m = re.match(r'(?:show|ls)(\()?\s*([^,/\\) ]*)(?:[,/\\ ]([^,/\\ )]+))*(?(1)\))', s, re.IGNORECASE) if m: name = m.group(2) code = m.group(3) name = name and name.strip().rstrip('s') # remove last 's' as in functions code = code and code.strip() if not name: pprint(sorted(['vars', 'options', 'mixins', 'functions'])) elif name in ('v', 'var', 'variable'): if code == '*': d = dict((k, v) for k, v in context.items()) pprint(d) elif code: d = dict((k, v) for k, v in context.items() if code in k) pprint(d) else: d = dict((k, v) for k, v in context.items() if k.startswith('$') and not k.startswith('$__')) pprint(d) elif name in ('o', 'opt', 'option'): if code == '*': d = dict((k, v) for k, v in options.items()) pprint(d) elif code: d = dict((k, v) for k, v in options.items() if code in k) pprint(d) else: d = dict((k, v) for k, v in options.items() if not k.startswith('@')) pprint(d) elif name in ('m', 'mix', 'mixin', 'f', 'func', 'funct', 'function'): if name.startswith('m'): name = 'mixin' elif name.startswith('f'): name = 'function' if code == '*': d = dict((k[len(name) + 2:], v) for k, v in options.items() if k.startswith('@' + name + ' ')) pprint(sorted(d)) elif code: d = dict((k, v) for k, v in options.items() if k.startswith('@' + name + ' ') and code in k) seen = set() for k, mixin in d.items(): mixin = getattr(mixin, 'mixin', mixin) fn_name, _, _ = k.partition(':') if fn_name not in seen: seen.add(fn_name) print fn_name + '(' + ', '.join(p + (': ' + mixin[1].get(p) if p in mixin[1] else '') for p in mixin[0]) + ') {' print ' ' + '\n '.join(l for l in mixin[2].split('\n')) print '}' else: d = dict((k[len(name) + 2:].split(':')[0], v) for k, v in options.items() if k.startswith('@' + name + ' ')) pprint(sorted(d)) continue elif s.startswith('$') and (':' in s or '=' in s): prop, value = [a.strip() for a in _prop_split_re.split(s, 1)] prop = css.do_glob_math(prop, context, options, rule, True) value = css.calculate(value, context, options, rule) context[prop] = value continue s = to_str(css.calculate(s, context, options, rule)) s = css.post_process(s) print s print "Bye!" elif options.watch: import time try: from watchdog.observers import Observer from watchdog.events import PatternMatchingEventHandler except ImportError: sys.stderr.write("Using watch functionality requires the `watchdog` library: http://pypi.python.org/pypi/watchdog/") sys.exit(1) if options.output and not os.path.isdir(options.output): sys.stderr.write("watch file output directory is invalid: '%s'" % (options.output)) sys.exit(2) class ScssEventHandler(PatternMatchingEventHandler): def __init__(self, *args, **kwargs): super(ScssEventHandler, self).__init__(*args, **kwargs) self.css = Scss(scss_opts={ 'compress': options.compress, 'debug_info': options.debug_info, }) self.output = options.output self.suffix = options.suffix def is_valid(self, path): return os.path.isfile(path) and path.endswith(".scss") and not os.path.basename(path).startswith("_") def process(self, path): if os.path.isdir(path): for f in os.listdir(path): full = os.path.join(path, f) if self.is_valid(full): self.compile(full) elif self.is_valid(path): self.compile(path) def compile(self, src_path): fname = os.path.basename(src_path) if fname.endswith(".scss"): fname = fname[:-5] if self.suffix: fname += "." + self.suffix fname += ".css" else: # you didn't give me a file of the correct type! return False if self.output: dest_path = os.path.join(self.output, fname) else: dest_path = os.path.join(os.path.dirname(src_path), fname) print "Compiling %s => %s" % (src_path, dest_path) src_file = open(src_path) dest_file = open(dest_path, 'w') dest_file.write(self.css.compile(src_file.read())) def on_moved(self, event): super(ScssEventHandler, self).on_moved(event) self.process(event.dest_path) def on_created(self, event): super(ScssEventHandler, self).on_created(event) self.process(event.src_path) def on_modified(self, event): super(ScssEventHandler, self).on_modified(event) self.process(event.src_path) event_handler = ScssEventHandler(patterns="*.scss") observer = Observer() observer.schedule(event_handler, path=options.watch, recursive=options.recursive) observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: observer.stop() observer.join() else: if options.output is not None: output = open(options.output, 'wt') else: output = sys.stdout css = Scss(scss_opts={ 'compress': options.compress, 'debug_info': options.debug_info, }) if args: for path in args: finput = open(path, 'rt') output.write(css.compile(finput.read())) else: output.write(css.compile(sys.stdin.read())) for f, t in profiling.items(): print >>sys.stderr, "%s took %03fs" % (f, t) if __name__ == "__main__": main() pyScss-1.1.5/scss/tool.pyc0000644000076500000240000003101512013742774016131 0ustar kronuzstaff00000000000000ó ŽÅ/Pc@@s×ddlmZddlZddlZddlZddlZddlmZddlZddlm Z m Z m Z m Z m Z ddlmZddlmZe jejƒd„ZedkrÓeƒndS( i(tabsolute_importN(tdeque(tScsstlogt spawn_ruletto_strt profiling(t_prop_split_re(t BUILD_INFOc(@së tjddƒddlm}m}m}|ddddd tƒ}|jd d d d ddƒ|jddddddƒ|jddd d ddƒ|jddddddƒ|jddddddƒ|jd d d dd!ƒ|jd"d d dd#ƒ|jd$d d%d&d'd(tdd)ƒ|jd*d+d d d|ƒ|jd,d-d d%d&d.d(tdd/ƒ|jd0d dd|ƒ|jd1d2d ddd3ƒ|jd4d5d d dd6ƒ||d7ƒ}|jd8d9ddd d:d&d;dd<ƒ|jd=d>ddd&d?dd@ƒ|jdAdBddd&dCddDƒ|j |ƒ|j ƒ\‰}dt _ ˆj rwdEt _ nˆjdk r•ˆjt _nˆjdk r³ˆjt _nˆjdk r»tt jdFƒrgt jjdGƒD]}|jƒ^qç}ntt jƒ}xtˆjD]i}x`|jtjdGƒjdHdGƒjdGƒD]4}|jƒ}|rL||krL|j|ƒqLqLWqWtt jdFƒr¯dGj|ƒt _q»|t _nˆjràddl} | j dIƒn ˆj!rñt"GHnö ˆj#r¦ ddJl$m$} yfddl%} ddl&} tj'j(dKƒ} y| j)| ƒWnt*k r[nX| j+| j,| ƒWnt-k rƒnXt.ƒ}|j/}|j0‰t1dL|dMˆƒ}dNt"GHxÞtr yt2dOƒjƒ}Wn%t3k rñHPnt4k rHPnX|d˜krPnxƒ|jdHƒD]r}|j5|jƒƒ}|sKq$n|j6dRƒrg}t7ƒ}t1dSdTdL|dMˆdU|ƒ|jddVƒdWgdE \‰‰ˆdXkrë|j8|dWgt9ƒ|dd|dˆˆƒ q$qd ˆdYkr+|j:|dWgt9ƒ|dd|dˆˆƒ q$qd ˆdZkrd dW}|j;|dWgt9ƒ|dd|dˆˆƒ |j<|ƒj=d[ƒ‰ˆr–|ˆ7}n|rç|j>j?|ƒ|j@ƒ|jA|jBƒj=d[ƒ‰ˆrç|ˆ7}qçn|jC|ƒ}|GHq$qd n`|d\ksL|j6d]ƒsL|j6d^ƒsL|j6d_ƒsL|j6d`ƒrÉ tDjEda|tDjFƒ}|rd |jGdEƒ‰|jGdbƒ‰ˆo ˆjƒj=dcƒ‰ˆo²ˆjƒ‰ˆsÚ| tHdddMdedfgƒƒq$ˆd™kryˆdjkrtIdk„|jJƒDƒƒ}| |ƒqÀ ˆrPtI‡fdl†|jJƒDƒƒ}| |ƒqÀ tIdm„|jJƒDƒƒ}| |ƒq$ˆdškr ˆdjkrºtIdq„ˆjJƒDƒƒ}| |ƒqÀ ˆrïtI‡fdr†ˆjJƒDƒƒ}| |ƒqÀ tIds„ˆjJƒDƒƒ}| |ƒq$ˆd›kr$ˆj6dtƒr< dv‰nˆj6dwƒrT dz‰nˆdjkr• tI‡fd{†ˆjJƒDƒƒ}| tH|ƒƒqÀ ˆr‹ tI‡‡fd|†ˆjJƒDƒƒ}t9ƒ}xñ|jJƒD]®\}‰tKˆdvˆƒ‰|jLd}ƒ\}}}||krÖ |jM|ƒ|d~dj‡fd€†ˆdDƒƒdGHd‚dƒjd„„ˆdEjd[ƒDƒƒGHd…GHqÖ qÖ WqÀ tI‡fd††ˆjJƒDƒƒ}| tH|ƒƒq$q$qd n›|j6d‡ƒrd d}|ksð dˆ|krd gtNj|dVƒD]}|jƒ^q \}}|jO||ˆ|tƒ}|jP||ˆ|ƒ}|||>> texittquitt@tfileidst propertiesits@options@imports@includes tlssshow(sshow sls(sls s?(?:show|ls)(\()?\s*([^,/\\) ]*)(?:[,/\\ ]([^,/\\ )]+))*(?(1)\))itstvarstmixinst functionstvtvartvariablet*cs@s!|]\}}||fVqdS(N((t.0tkR1((s scss/tool.pys ªsc3@s-|]#\}}ˆ|kr||fVqdS(N((R5R6R1(tcode(s scss/tool.pys ­scs@s@|]6\}}|jdƒr|jdƒ r||fVqdS(t$s$__N(t startswith(R5R6R1((s scss/tool.pys °stotopttoptioncs@s!|]\}}||fVqdS(N((R5R6R1((s scss/tool.pys ´sc3@s-|]#\}}ˆ|kr||fVqdS(N((R5R6R1(R7(s scss/tool.pys ·scs@s0|]&\}}|jdƒs||fVqdS(R(N(R9(R5R6R1((s scss/tool.pys ºstmtmixtmixintftfunctfuncttfunctionc3@sF|]<\}}|jdˆdƒr|tˆƒd|fVqdS(R(t iN(R9tlen(R5R6R1(tname(s scss/tool.pys Âsc3@sD|]:\}}|jdˆdƒrˆ|kr||fVqdS(R(RDN(R9(R5R6R1(R7RF(s scss/tool.pys Åst:t(s, c3@s@|]6}||ˆdkr3dˆdj|ƒndVqdS(is: R+N(tget(R5tp(R?(s scss/tool.pys Ìss) {s s cs@s|] }|VqdS(N((R5tl((s scss/tool.pys Íst}c3@sS|]I\}}|jdˆdƒr|tˆƒdjdƒd|fVqdS(R(RDiRGiN(R9RER (R5R6R1(RF(s scss/tool.pys ÐsR8t=sBye!(tObserver(tPatternMatchingEventHandlers`Using watch functionality requires the `watchdog` library: http://pypi.python.org/pypi/watchdog/s,watch file output directory is invalid: '%s'tScssEventHandlerc@sbeZ‡‡fd†Zd„Zd„Zd„Z‡fd†Z‡fd†Z‡fd†ZRS(c@s[tˆ|ƒj||Žtdiˆjd6ˆjd6ƒ|_ˆj|_ˆj|_dS(Nt scss_optsRR(tsupert__init__RRRtcsstoutputtsuffix(tselftargstkwargs(RPR%(s scss/tool.pyRSês    cS@s;tjj|ƒo:|jdƒo:tjj|ƒjdƒ S(Ns.scsst_(tostpathtisfiletendswithtbasenameR9(RWR\((s scss/tool.pytis_validóscS@s†tjj|ƒrcxmtj|ƒD]:}tjj||ƒ}|j|ƒr"|j|ƒq"q"Wn|j|ƒr‚|j|ƒndS(N(R[R\tisdirtlistdirtjoinR`tcompile(RWR\R@tfull((s scss/tool.pytprocessöscS@sëtjj|ƒ}|jdƒrU|d }|jrH|d|j7}n|d7}ntS|jr}tjj|j|ƒ}n!tjjtjj|ƒ|ƒ}d||fGHt |ƒ}t |dƒ}|j |j j |j ƒƒƒdS(Ns.scssiûÿÿÿt.s.csssCompiling %s => %stw(R[R\R_R^RVtFalseRURctdirnametopentwriteRTRdtread(RWtsrc_pathtfnamet dest_pathtsrc_filet dest_file((s scss/tool.pyRdÿs    ! c@s*tˆ|ƒj|ƒ|j|jƒdS(N(RRton_movedRfRp(RWtevent(RP(s scss/tool.pyRssc@s*tˆ|ƒj|ƒ|j|jƒdS(N(RRt on_createdRfRn(RWRt(RP(s scss/tool.pyRusc@s*tˆ|ƒj|ƒ|j|jƒdS(N(RRt on_modifiedRfRn(RWRt(RP(s scss/tool.pyRvs( t__name__t __module__RSR`RfRdRsRuRv((RPR%(s scss/tool.pyRPés  tpatternss*.scssR\t recursivetwtRQtrts %s took %03fs(sexitsquit(R1svarR3(R:R;soption(R=R>smixinR@sfuncsfunctsfunction(jtloggingt basicConfigtoptparseR R R Rit add_optiontTruetadd_option_groupt parse_argstscsst VERBOSITYttimeRtNonet STATIC_ROOTRt ASSETS_ROOTRthasattrt LOAD_PATHSR tstriptlisttreplaceR[tpathsepRRcttesttdoctestttestfiletversionRt interactiveR#tatexittreadlineR\t expandusertread_history_filetIOErrortregistertwrite_history_filet ImportErrorRt scss_varsRQRt raw_inputtEOFErrortKeyboardInterruptt load_stringR9Rt_settle_optionstsett _do_importt _do_includet_print_propertiestrstriptchildrent extendlefttparse_childrent _create_csstrulest post_processtretmatcht IGNORECASEtgrouptsortedtdicttitemstgetattrt partitiontaddRt do_glob_matht calculateRtwatchtwatchdog.observersRNtwatchdog.eventsROtsyststderrRlR&RURatscheduleRztstarttsleeptstopRktstdoutRRRdRmtstdinR((R R R tparsert paths_groupRXRJtload_path_listt path_paramR‘R#R•R–thistfileRTR$truleR-R*R¨t final_contR=tdtseenR6tfn_nameRZtatproptvalueR†RNROt event_handlertobserverRUR\tfinputR@tt((R7RPR?RFR%s scss/tool.pytmains´         .1                   # . . .   H   "     "      "%   .)" '1     7         #t__main__(t __future__RR}R[R®R½t collectionsRR„RRRRRRtscss.scss_metaRtsetLeveltINFORÖRw(((s scss/tool.pyts     ( ÿ. pyScss-1.1.5/setup.cfg0000644000076500000240000000007312107522130015267 0ustar kronuzstaff00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 pyScss-1.1.5/setup.py0000644000076500000240000000753112013740760015175 0ustar kronuzstaff00000000000000#!/usr/bin/env python import os import sys from setuptools import setup, Extension, Feature from distutils.command.build_ext import build_ext from distutils.errors import CCompilerError, DistutilsExecError, \ DistutilsPlatformError from scss.scss_meta import PROJECT, URL, VERSION, AUTHOR, AUTHOR_EMAIL, LICENSE, DOWNLOAD_URL # fail safe compilation shamelessly stolen from the simplejson # setup.py file. Original author: Bob Ippolito is_jython = 'java' in sys.platform is_pypy = hasattr(sys, 'pypy_version_info') speedups = Feature( 'optional C speed-enhancement module', standard=True, ext_modules=[ Extension( 'scss._speedups', sources=['scss/src/_speedups.c', 'scss/src/block_locator.c', 'scss/src/scanner.c'], libraries=['pcre'] ), ], ) ext_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError) if sys.platform == 'win32' and sys.version_info > (2, 6): # 2.6's distutils.msvc9compiler can raise an IOError when failing to # find the compiler ext_errors += (IOError,) extra = {} if sys.version_info >= (3, 0): extra['use_2to3'] = True class BuildFailed(Exception): pass class ve_build_ext(build_ext): """This class allows C extension building to fail.""" def run(self): try: build_ext.run(self) except DistutilsPlatformError: raise BuildFailed() def build_extension(self, ext): try: build_ext.build_extension(self, ext) except ext_errors: raise BuildFailed() except ValueError: # this can happen on Windows 64 bit, see Python issue 7511 if "'path'" in str(sys.exc_info()[1]): # works with Python 2 and 3 raise BuildFailed() raise def echo(msg=''): sys.stdout.write(msg + '\n') def read(fname): try: return open(os.path.join(os.path.dirname(__file__), fname)).read().strip() except IOError: return '' def run_setup(with_binary): features = {} if with_binary: features['speedups'] = speedups setup( name=PROJECT, version=VERSION, description=read('DESCRIPTION'), long_description=read('README.rst'), author=AUTHOR, author_email=AUTHOR_EMAIL, url=URL, download_url=DOWNLOAD_URL, license=LICENSE, keywords='css oocss xcss sass scss less precompiler', classifiers=[ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Topic :: Software Development :: Code Generators", "Topic :: Text Processing :: Markup", "Topic :: Software Development :: Libraries :: Python Modules" ], packages=['scss'], package_data={'scss': ['tests.rst']}, cmdclass={'build_ext': ve_build_ext}, features=features, entry_points=""" [console_scripts] pyscss = scss.tool:main """, **extra ) def try_building_extension(): try: run_setup(True) except BuildFailed: LINE = '=' * 74 BUILD_EXT_WARNING = 'WARNING: The C extension could not be ' \ 'compiled, speedups are not enabled.' echo(LINE) echo(BUILD_EXT_WARNING) echo('Failure information, if any, is above.') echo('Retrying the build without the C extension now.') echo() run_setup(False) echo(LINE) echo(BUILD_EXT_WARNING) echo('Plain-Python installation succeeded.') echo(LINE) if not (is_pypy or is_jython): try_building_extension() else: run_setup(False)