1# -*- coding: utf8 -*- 2""" 3.. module:: lesscpy.plib.property 4 :synopsis: Property node. 5 6 Copyright (c) 7 See LICENSE for details. 8.. moduleauthor:: Johann T. Mariusson <jtm@robot.is> 9""" 10import re 11from .node import Node 12 13 14class Property(Node): 15 """Represents CSS property declaration. 16 """ 17 18 def parse(self, scope): 19 """Parse node 20 args: 21 scope (Scope): current scope 22 raises: 23 SyntaxError 24 returns: 25 self 26 """ 27 if not self.parsed: 28 if len(self.tokens) > 2: 29 property, style, _ = self.tokens 30 self.important = True 31 else: 32 property, style = self.tokens 33 self.important = False 34 self.property = ''.join(property) 35 self.parsed = [] 36 if style: 37 style = self.preprocess(style) 38 self.parsed = self.process(style, scope) 39 return self 40 41 def preprocess(self, style): 42 """Hackish preprocessing from font shorthand tags. 43 Skips expression parse on certain tags. 44 args: 45 style (list): . 46 returns: 47 list 48 """ 49 if self.property == 'font': 50 style = [ 51 ''.join(u.expression()) if hasattr(u, 'expression') else u 52 for u in style 53 ] 54 else: 55 style = [(u, ' ') if hasattr(u, 'expression') else u 56 for u in style] 57 return style 58 59 def fmt(self, fills): 60 """ Format node 61 args: 62 fills (dict): replacements 63 returns: 64 str 65 """ 66 f = "%(tab)s%(property)s:%(ws)s%(style)s%(important)s;%(nl)s" 67 imp = ' !important' if self.important else '' 68 if fills['nl']: 69 self.parsed = [ 70 ',%s' % fills['ws'] if p == ',' else p for p in self.parsed 71 ] 72 style = ''.join([ 73 p.fmt(fills) if hasattr(p, 'fmt') else str(p) for p in self.parsed 74 ]) 75 # IE cannot handle no space after url() 76 style = re.sub("(url\([^\)]*\))([^\s,])", "\\1 \\2", style) 77 fills.update({ 78 'property': self.property, 79 'style': style.strip(), 80 'important': imp 81 }) 82 return f % fills 83 84 def copy(self): 85 """ Return a full copy of self 86 Returns: 87 Property object 88 """ 89 return Property([t for t in self.tokens], 0) 90