Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

experimental support for Compass features in Sass

  • Loading branch information...
commit 3d1dc558e056f79cb5051e0619b7041572a727f5 1 parent 11d56d5
Waldemar Kornewald authored
View
5 CHANGELOG.rst
@@ -1,12 +1,13 @@
Changelog
=============================================================
-Version 1.9.3 (in development)
+Version 1.10 (in development)
-------------------------------------------------------------
+* Added Compass support to Sass filter. You now have to install both Compass and Sass. Import Sass/Compass frameworks via ``manage.py importsassframeworks``.
* Fixed CoffeeScript support on OSX
* Added "Content-Length" response header for files served in dev mode (needed for Flash). Thanks to "sayane" for the patch.
-* Fixed typo which resulted in broken support for .html assets. Thanks to "pendletongp" for the patch.
+* Fixed typo which resulted in broken support for ``.html`` assets. Thanks to "pendletongp" for the patch.
* Now showing instructive error message when Sass can't be found
* Use correct output path for ``_generated_media_names.py`` even when ``manage.py generatemedia`` is not started from the project root. Thanks to "pendletongp" for the patch.
View
2  MANIFEST.in
@@ -1,7 +1,7 @@
include LICENSE
include CHANGELOG.rst
include README.rst
-recursive-include mediagenerator *.html *.manifest *.gif *.jpg *.jpeg *.png *.js *.css *.sass
+recursive-include mediagenerator *.html *.manifest *.gif *.jpg *.jpeg *.png *.js *.css *.sass *.rb
recursive-include mediagenerator/filters/pyjslibs *.py
recursive-include base_project *.py *.html *.manifest *.gif *.jpg *.jpeg *.png *.js *.css *.sass
prune base_project _generated_media_names.py
View
9 mediagenerator/filters/sass.py
@@ -10,6 +10,7 @@
# Emits extra debug info that can be used by the FireSass Firebug plugin
SASS_DEBUG_INFO = getattr(settings, 'SASS_DEBUG_INFO', False)
+SASS_FRAMEWORKS = getattr(settings, 'SASS_FRAMEWORKS', ())
_RE_FLAGS = re.MULTILINE | re.UNICODE
multi_line_comment_re = re.compile(r'/\*.*?\*/', _RE_FLAGS | re.DOTALL)
@@ -57,7 +58,10 @@ def get_dev_output_names(self, variation):
yield self.main_module, self._compiled_hash
def _compile(self, debug=False):
- run = ['sass', '-C', '-t', 'expanded']
+ extensions = os.path.join(os.path.dirname(__file__), 'sass_compass.rb')
+ run = ['sass', '-C', '-t', 'expanded', '--require', extensions]
+ for framework in SASS_FRAMEWORKS:
+ run.extend(('--require', framework))
if debug:
run.append('--line-numbers')
if SASS_DEBUG_INFO:
@@ -72,7 +76,8 @@ def _compile(self, debug=False):
return output
except Exception, e:
raise ValueError("Failed to execute Sass. Please make sure that "
- "you have installed Sass (http://sass-lang.com).\n"
+ "you have installed Sass (http://sass-lang.com) and "
+ "Compass (http://compass-style.org).\n"
"Error was: %s" % e)
def _regenerate(self, debug=False):
View
65 mediagenerator/filters/sass_compass.rb
@@ -0,0 +1,65 @@
+require "compass"
+
+module Compass::SassExtensions::Functions::Urls
+
+ def stylesheet_url(path, only_path = Sass::Script::Bool.new(false))
+ if only_path.to_bool
+ Sass::Script::String.new(clean_path(path))
+ else
+ clean_url(path)
+ end
+ end
+
+ def font_url(path, only_path = Sass::Script::Bool.new(false))
+ path = path.value # get to the string value of the literal.
+
+ # Short curcuit if they have provided an absolute url.
+ if absolute_path?(path)
+ return Sass::Script::String.new("url(#{path})")
+ end
+
+ if only_path.to_bool
+ Sass::Script::String.new(clean_path(path))
+ else
+ clean_url(path)
+ end
+ end
+
+ def image_url(path, only_path = Sass::Script::Bool.new(false))
+ print "#{@options}\n"
+ path = path.value # get to the string value of the literal.
+
+ if absolute_path?(path)
+ # Short curcuit if they have provided an absolute url.
+ return Sass::Script::String.new("url(#{path})")
+ end
+
+ if only_path.to_bool
+ Sass::Script::String.new(clean_path(path))
+ else
+ clean_url(path)
+ end
+ end
+
+ private
+
+ # Emits a path, taking off any leading "./"
+ def clean_path(url)
+ url = url.to_s
+ url = url[0..1] == "./" ? url[2..-1] : url
+ end
+
+ # Emits a url, taking off any leading "./"
+ def clean_url(url)
+ Sass::Script::String.new("url('#{clean_path(url)}')")
+ end
+
+ def absolute_path?(path)
+ path[0..0] == "/" || path[0..3] == "http"
+ end
+
+end
+
+module Sass::Script::Functions
+ include Compass::SassExtensions::Functions::Urls
+end
View
11 mediagenerator/filters/sass_paths.rb
@@ -0,0 +1,11 @@
+require "sass"
+require "compass"
+
+ARGV.each do |arg|
+ require arg
+end
+
+Compass::Frameworks::ALL.each do |framework|
+ next if framework.name =~ /^_/
+ print "#{File.expand_path(framework.stylesheets_directory)}\n"
+end
View
70 mediagenerator/management/commands/importsassframeworks.py
@@ -0,0 +1,70 @@
+from ...filters import sass
+from ...utils import get_media_dirs
+from django.core.management.base import NoArgsCommand
+from subprocess import Popen, PIPE
+import os
+import shutil
+import sys
+import __main__
+
+_frameworks_dir = 'imported-sass-frameworks'
+if hasattr(__main__, '__file__'):
+ _root = os.path.dirname(__main__.__file__)
+ _frameworks_dir = os.path.join(_root, _frameworks_dir)
+FRAMEWORKS_DIR = os.path.normcase(os.path.abspath(_frameworks_dir))
+
+PATHS_SCRIPT = os.path.join(os.path.dirname(sass.__file__), 'sass_paths.rb')
+
+def copy_children(src, dst):
+ for item in os.listdir(src):
+ path = os.path.join(src, item)
+ copy_fs_node(path, dst)
+
+def copy_fs_node(src, dst):
+ basename = os.path.basename(src)
+ dst = os.path.join(dst, basename)
+ if os.path.isfile(src):
+ shutil.copy(src, dst)
+ elif os.path.isdir(src):
+ shutil.copytree(src, dst)
+ else:
+ raise ValueError("Don't know how to copy file system node: %s" % src)
+
+class Command(NoArgsCommand):
+ help = 'Copies Sass/Compass frameworks into the current project.'
+
+ requires_model_validation = False
+
+ def handle_noargs(self, **options):
+ if os.path.exists(FRAMEWORKS_DIR):
+ shutil.rmtree(FRAMEWORKS_DIR)
+ os.mkdir(FRAMEWORKS_DIR)
+ for path in self.get_framework_paths():
+ copy_children(path, FRAMEWORKS_DIR)
+
+ if FRAMEWORKS_DIR not in get_media_dirs():
+ sys.stderr.write('Please add the "%(dir)s" '
+ 'folder to your GLOBAL_MEDIA_DIRS setting '
+ 'like this:\n\n'
+ 'GLOBAL_MEDIA_DIRS = (\n'
+ ' ...\n'
+ " os.path.join(os.path.dirname(__file__),\n"
+ " '%(dir)s'),\n"
+ " ...\n"
+ ")\n" % {'dir': os.path.basename(FRAMEWORKS_DIR)})
+
+ def get_framework_paths(self):
+ run = ['ruby', PATHS_SCRIPT]
+ run.extend(sass.SASS_FRAMEWORKS)
+ try:
+ cmd = Popen(run, universal_newlines=True,
+ stdin=PIPE, stdout=PIPE, stderr=PIPE)
+ output, error = cmd.communicate()
+ assert cmd.wait() == 0, 'Command returned bad result:\n%s' % error
+ return map(os.path.abspath, filter(None, output.split('\n')))
+ except Exception, e:
+ raise ValueError("Failed to execute an internal Ruby script. "
+ "Please make sure that you have installed Ruby "
+ "(http://ruby-lang.org), Sass (http://sass-lang.com), and "
+ "Compass (http://compass-style.org).\n"
+ "Error was: %s" % e)
Please sign in to comment.
Something went wrong with that request. Please try again.