| OLD | NEW |
| (Empty) |
| 1 import sys, os | |
| 2 from os.path import abspath, dirname, join, normpath | |
| 3 from scss import OPRT | |
| 4 from scss.base import ParseNode, Empty, Node, IncludeNode | |
| 5 from scss.function import FUNCTION_LIST, unknown, warn | |
| 6 from scss.value import StringValue, Value, BooleanValue, NumberValue, QuotedStri
ngValue | |
| 7 | |
| 8 class Option(Empty): | |
| 9 """ Set parser option. | |
| 10 """ | |
| 11 def parse(self, target): | |
| 12 opts = map(lambda (x, y): (x.value, BooleanValue(y).value), | |
| 13 zip(*[iter(self.data[1:])]*2)) | |
| 14 for v in opts: | |
| 15 self.root.set_opt(*v) | |
| 16 | |
| 17 | |
| 18 class Variable(Value, ParseNode): | |
| 19 | |
| 20 def_value = StringValue('none') | |
| 21 | |
| 22 @classmethod | |
| 23 def _do_op(cls, self, other, op): | |
| 24 return self.value._do_op(self.value, other, op) | |
| 25 | |
| 26 @classmethod | |
| 27 def _do_cmps(cls, self, other, op): | |
| 28 return self.value._do_cmps(self.value, other, op) | |
| 29 | |
| 30 def __nonzero__(self): | |
| 31 return True | |
| 32 | |
| 33 @property | |
| 34 def value(self): | |
| 35 name = self.data[0].strip('-$') | |
| 36 minus = self.data[0][0] == '-' | |
| 37 value = self.ctx.get(name) or self.root.ctx.get(name, self.def_value) | |
| 38 return (0 - value) if minus else value | |
| 39 | |
| 40 | |
| 41 class Variables(ParseNode, Empty): | |
| 42 pass | |
| 43 | |
| 44 | |
| 45 class Expression(Variable): | |
| 46 | |
| 47 @property | |
| 48 def value(self): | |
| 49 it = iter(self.data) | |
| 50 try: | |
| 51 first = next(it) | |
| 52 while True: | |
| 53 res = next(it) | |
| 54 op = OPRT.get(res.strip(), None) | |
| 55 if op: | |
| 56 second = next(it) | |
| 57 first = op(first, second) | |
| 58 | |
| 59 if op == OPRT['and'] and not first: | |
| 60 raise StopIteration | |
| 61 | |
| 62 elif op == OPRT['or'] and first: | |
| 63 raise StopIteration | |
| 64 | |
| 65 except StopIteration: | |
| 66 while isinstance(first, Variable): | |
| 67 first = first.value | |
| 68 return first | |
| 69 | |
| 70 | |
| 71 class SepValString(Expression): | |
| 72 | |
| 73 @property | |
| 74 def value(self): | |
| 75 return ', '.join(str(e.value) for e in self.data) | |
| 76 | |
| 77 | |
| 78 class Function(Expression): | |
| 79 | |
| 80 @property | |
| 81 def value(self): | |
| 82 name = self.data[0] | |
| 83 func_name_a = "%s:%d" % (name, len(self.data) - 1) | |
| 84 func_name_n = "%s:n" % name | |
| 85 func = FUNCTION_LIST.get(func_name_a, FUNCTION_LIST.get(func_name_n, unk
nown)) | |
| 86 | |
| 87 params = map(lambda v: v.value, self.data[1:]) | |
| 88 return func(*params, root=self.root, name=name) | |
| 89 | |
| 90 | |
| 91 class FunctionDefinition(Empty): | |
| 92 | |
| 93 def parse(self, target): | |
| 94 name = self.data[1].value | |
| 95 params = self.data[2] | |
| 96 func_name = '%s:%s' % (name, len(params)) | |
| 97 FUNCTION_LIST[func_name] = self.wrapper | |
| 98 | |
| 99 def wrapper(self, *args, **kwargs): | |
| 100 self.ctx = Mixin.get_context(self.data[2], args) | |
| 101 for node in self.data[2:]: | |
| 102 if isinstance(node, FunctionReturn): | |
| 103 return node.value | |
| 104 elif isinstance(node, Node): | |
| 105 node.parse(self) | |
| 106 | |
| 107 | |
| 108 class FunctionReturn(Variable): | |
| 109 | |
| 110 @property | |
| 111 def value(self): | |
| 112 return self.data[1] | |
| 113 | |
| 114 | |
| 115 class MixinParam(Empty): | |
| 116 def __init__(self, s, n, t): | |
| 117 super(MixinParam, self).__init__(s, n, t) | |
| 118 self.name = self.data[0].data[0][1:] | |
| 119 self.value = self.data[1] if len(self.data) > 1 else None | |
| 120 | |
| 121 | |
| 122 class Extend(Empty): | |
| 123 | |
| 124 def parse(self, target): | |
| 125 for rule in self.root.cache['rset'][self.data[1]]: | |
| 126 rule.name.extend(target.name) | |
| 127 | |
| 128 | |
| 129 class Mixin(Empty): | |
| 130 | |
| 131 def __init__(self, s, n, t): | |
| 132 super(Mixin, self).__init__(s, n, t) | |
| 133 self.name = str(self.data[1]) | |
| 134 self.default = self.data[2] | |
| 135 | |
| 136 def parse(self, target): | |
| 137 self.root.cache['mix'][self.name] = self | |
| 138 | |
| 139 def include(self, target, params): | |
| 140 ctx = self.get_context(self.default, params) | |
| 141 if target.ctx: | |
| 142 ctx.update(target.ctx) | |
| 143 | |
| 144 self.ctx = ctx | |
| 145 for n in params: | |
| 146 n.parse(self) | |
| 147 | |
| 148 for node in self.data[3:]: | |
| 149 if isinstance(node, Node): | |
| 150 copy = node.copy() | |
| 151 copy.ctx = ctx | |
| 152 copy.parse(target) | |
| 153 | |
| 154 @staticmethod | |
| 155 def get_context(default, params=''): | |
| 156 test = map(lambda x, y: (x, y), default, params) | |
| 157 return dict(( mp.name, v or mp.value ) for mp, v in test if mp) | |
| 158 | |
| 159 | |
| 160 class Include(IncludeNode): | |
| 161 | |
| 162 def parse(self, target): | |
| 163 from scss import parser | |
| 164 | |
| 165 includeValue = self.data[1] | |
| 166 if isinstance(target, ParseNode) and not(isinstance(includeValue, | |
| 167 QuotedStringValue)): | |
| 168 name = str(includeValue) | |
| 169 params = self.data[2:] | |
| 170 mixin = self.root.cache['mix'].get(name) | |
| 171 if mixin: | |
| 172 mixin.include(target, params) | |
| 173 else: | |
| 174 warn("Required mixin not found: %s:%d." % ( name, len(params))) | |
| 175 elif isinstance(target, parser.Stylesheet) and isinstance(includeValue, | |
| 176 QuotedStringValue): | |
| 177 # @include "scss file to include" | |
| 178 # Parse this file for more class names to emit in Dart class. | |
| 179 options = target.currentOptions | |
| 180 f = target.currentFile | |
| 181 | |
| 182 s = parser.Stylesheet(options=target.currentOptions) | |
| 183 f = target.currentFile | |
| 184 path = dirname(abspath(f.name)) | |
| 185 includePath = normpath('{0}/{1}'.format(path, self.data[1].value)) | |
| 186 f = open(includePath, 'r') | |
| 187 nodes = s.loadReturnNodes(f) | |
| 188 target.addInclude(includeValue.value, nodes) | |
| 189 | |
| 190 class If(IncludeNode): | |
| 191 | |
| 192 def parse(self, target): | |
| 193 self.data[0].parse(self) | |
| 194 target.ctx.update(self.ctx) | |
| 195 if isinstance(target, ParseNode): | |
| 196 if self.data[0].value: | |
| 197 self.data[1].parse(target) | |
| 198 elif len(self.data) > 2: | |
| 199 self.data[2].parse(target) | |
| 200 | |
| 201 | |
| 202 class For(IncludeNode): | |
| 203 def parse(self, target): | |
| 204 if isinstance(target, ParseNode): | |
| 205 name = self.data[1].data[0][1:] | |
| 206 for i in xrange(int(float(self.data[2])), int(float(self.data[3]))+1
): | |
| 207 body = self.data[4].copy() | |
| 208 body.ctx.update({name: NumberValue(i)}) | |
| 209 body.parse(target) | |
| 210 | |
| 211 class Stylet(Empty): | |
| 212 def __init__(self, s, n, t): | |
| 213 super(Stylet, self).__init__(s, n, t) | |
| 214 self.name = str(self.data[1]) | |
| OLD | NEW |