PageRenderTime 80ms CodeModel.GetById 53ms app.highlight 21ms RepoModel.GetById 1ms app.codeStats 1ms

/hyde/ext/plugins/stylus.py

http://github.com/hyde/hyde
Python | 117 lines | 92 code | 9 blank | 16 comment | 7 complexity | ef9b20e0505d59a0eaa54a12f458c71d MD5 | raw file
  1# -*- coding: utf-8 -*-
  2"""
  3Less css plugin
  4"""
  5
  6from hyde.plugin import CLTransformer
  7from hyde.fs import File
  8
  9import re
 10import subprocess
 11
 12
 13class StylusPlugin(CLTransformer):
 14    """
 15    The plugin class for less css
 16    """
 17
 18    def __init__(self, site):
 19        super(StylusPlugin, self).__init__(site)
 20
 21    def begin_site(self):
 22        """
 23        Find all the styl files and set their relative deploy path.
 24        """
 25        for resource in self.site.content.walk_resources():
 26            if resource.source_file.kind == 'styl':
 27                new_name = resource.source_file.name_without_extension + ".css"
 28                target_folder = File(resource.relative_deploy_path).parent
 29                resource.relative_deploy_path = target_folder.child(new_name)
 30
 31    def begin_text_resource(self, resource, text):
 32        """
 33        Replace @import statements with {% include %} statements.
 34        """
 35
 36        if not resource.source_file.kind == 'styl':
 37            return
 38        import_finder = re.compile(
 39                    '^\\s*@import\s+(?:\'|\")([^\'\"]*)(?:\'|\")\s*\;?\s*$',
 40                    re.MULTILINE)
 41
 42        def import_to_include(match):
 43            """
 44            Converts a css import statement to include statemnt.
 45            """
 46            if not match.lastindex:
 47                return ''
 48            path = match.groups(1)[0]
 49            afile = File(File(resource.source_file.parent.child(path)).fully_expanded_path)
 50            if len(afile.kind.strip()) == 0:
 51                afile = File(afile.path + '.styl')
 52
 53            ref = self.site.content.resource_from_path(afile.path)
 54
 55            if not ref:
 56                try:
 57                    include = self.settings.args.include
 58                except AttributeError:
 59                    include = False
 60                if not include:
 61                    raise self.template.exception_class(
 62                        "Cannot import from path [%s]" % afile.path)
 63            else:
 64                ref.is_processable = False
 65                return "\n" + \
 66                        self.template.get_include_statement(ref.relative_path) + \
 67                        "\n"
 68            return '@import "' + path + '"\n'
 69
 70        text = import_finder.sub(import_to_include, text)
 71        return text
 72
 73    @property
 74    def defaults(self):
 75        """
 76        Returns `compress` if not in development mode.
 77        """
 78        try:
 79            mode = self.site.config.mode
 80        except AttributeError:
 81            mode = "production"
 82
 83        defaults = {"compress":""}
 84        if mode.startswith('dev'):
 85            defaults = {}
 86        return defaults
 87
 88    @property
 89    def plugin_name(self):
 90        """
 91        The name of the plugin.
 92        """
 93        return "stylus"
 94
 95    def text_resource_complete(self, resource, text):
 96        """
 97        Save the file to a temporary place and run stylus compiler.
 98        Read the generated file and return the text as output.
 99        Set the target path to have a css extension.
100        """
101        if not resource.source_file.kind == 'styl':
102            return
103        stylus = self.app
104        source = File.make_temp(text)
105        target = source
106        supported = [("compress", "c"), ("include", "I")]
107
108        args = [unicode(stylus)]
109        args.extend(self.process_args(supported))
110        args.append(unicode(source))
111        try:
112            self.call_app(args)
113        except subprocess.CalledProcessError, e:
114            raise self.template.exception_class(
115                    "Cannot process %s. Error occurred when "
116                    "processing [%s]" % (stylus.name, resource.source_file))
117        return target.read_all()