/hyde/ext/plugins/stylus.py
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()