def __init__(self, app, static_dir=None, asset_dir=None, load_paths=None): ''' See :ref:`scss_discovery_rules` and :ref:`static_discovery_rules` for more information about the impact of ``static_dir`` and ``asset_dir`` parameters. Parameters here has preedence over Parameters found in the application config. :param app: Your Flask Application :param static_dir: The path to the ``static`` directory of your application (optional) :param asset_dir: The path to the ``assets`` directory where Flask-Scss will search ``.scss`` files (optional) :param load_paths: A list of folders to add to pyScss load_paths (for ex., the path to a library like Compass) ''' if not load_paths: load_paths = [] self.app = app self.asset_dir = self.set_asset_dir(asset_dir) self.static_dir = self.set_static_dir(static_dir) self.assets = {} self.partials = {} load_path_list = ([self.asset_dir] if self.asset_dir else []) \ + (load_paths or app.config.get('SCSS_LOAD_PATHS', [])) # pyScss.log = app.logger self.compiler = Compiler(search_path=load_path_list) if self.app.testing or self.app.debug: self.set_hooks()
def compile_file(self, path: str): """Compiles SCSS into CSS.""" # don't compile non-scss files if os.path.splitext(path)[1] != ".scss": return # the name of the compiled file without extensions name = Path(path).stem output_path = os.path.join(SCSSAutoCompiler.OUTPUT_DIR, name + ".css") try: # ensure these folders exist os.makedirs(os.path.dirname(output_path)) except FileExistsError: pass try: print(f"compiling SCSS at {path} => {output_path}") with open(output_path, "w") as f: f.write(Compiler(search_path=("style/", )).compile(path)) self.octogon.on_compile(name, "scss", output_path) except Exception as e: print("failed to compile scss: ") print(e)
def __init__(self, is_sass=False): # TODO it would be lovely to get these out of here, somehow self.namespace = Namespace(variables=_default_scss_vars) self.compiler = Compiler(namespace=self.namespace) self.compilation = self.compiler.make_compilation() self.legacy_compiler_options = {} self.source_file = SourceFile.from_string('', '<shell>', is_sass=is_sass) self.calculator = Calculator(self.namespace)
def clean(self): compiler = Compiler( search_path=getattr(settings, 'SASS_SEARCH_PATHS', []), output_style='compressed' if self.minify else 'nested') try: self.output = compiler.compile_string(self.source) except (ValueError, SassSyntaxError) as e: import traceback traceback.print_exc() raise ValidationError({'source': str(e)})
def setup(self): try: from scss.compiler import Compiler except ImportError: raise EnvironmentError('The "pyScss" package is not installed.') else: search_path = [ path.join(path.abspath(path.dirname(__file__)), 'static', 'scss') ] self.compiler = Compiler(search_path=search_path)
def compile(self, scss_string=None, scss_file=None, source_files=None, super_selector=None, filename=None, is_sass=None, line_numbers=True, import_static_css=False): """Compile Sass to CSS. Returns a single CSS string. This method is DEPRECATED; see :mod:`scss.compiler` instead. """ # Derive our root namespace self.scss_vars = _default_scss_vars.copy() if self._scss_vars is not None: self.scss_vars.update(self._scss_vars) root_namespace = Namespace( variables=self.scss_vars, functions=self._library, ) # Figure out search paths. Fall back from provided explicitly to # defined globally to just searching the current directory search_paths = ['.'] if self._search_paths is not None: assert not isinstance(self._search_paths, six.string_types), \ "`search_paths` should be an iterable, not a string" search_paths.extend(self._search_paths) else: if config.LOAD_PATHS: if isinstance(config.LOAD_PATHS, six.string_types): # Back-compat: allow comma-delimited search_paths.extend(config.LOAD_PATHS.split(',')) else: search_paths.extend(config.LOAD_PATHS) search_paths.extend(self._scss_opts.get('load_paths', [])) # Normalize a few old styles of options output_style = self._scss_opts.get('style', config.STYLE) if output_style is True: output_style = 'compressed' elif output_style is False: output_style = 'legacy' fixed_search_path = [] for path in search_paths: if isinstance(path, six.string_types): fixed_search_path.append(Path(path)) else: fixed_search_path.append(path) # Build the compiler compiler = Compiler( namespace=root_namespace, extensions=[ CoreExtension, ExtraExtension, FontsExtension, CompassExtension, BootstrapExtension, ], search_path=fixed_search_path, import_static_css=import_static_css, live_errors=self.live_errors, generate_source_map=self._scss_opts.get('debug_info', False), output_style=output_style, warn_unused_imports=self._scss_opts.get('warn_unused', False), ignore_parse_errors=config.DEBUG, loops_have_own_scopes=config.CONTROL_SCOPING, undefined_variables_fatal=config.FATAL_UNDEFINED, super_selector=super_selector or self.super_selector, ) # Gonna add the source files manually compilation = compiler.make_compilation() # Inject the files we know about # TODO how does this work with the expectation of absoluteness if source_files is not None: for source in source_files: compilation.add_source(source) elif scss_string is not None: source = SourceFile.from_string( scss_string, relpath=filename, is_sass=is_sass, ) compilation.add_source(source) elif scss_file is not None: # This is now the only way to allow forcibly overriding the # filename a source "thinks" it is with open(scss_file, 'rb') as f: source = SourceFile.from_file( f, relpath=filename or scss_file, is_sass=is_sass, ) compilation.add_source(source) # Plus the ones from the constructor if self._scss_files: for name, contents in list(self._scss_files.items()): source = SourceFile.from_string(contents, relpath=name) compilation.add_source(source) return compiler.call_and_catch_errors(compilation.run)