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