checkpoint mixins
This commit is contained in:
@@ -18,6 +18,18 @@ from . import utility
|
||||
from .scope import Scope
|
||||
from .color import Color
|
||||
from lesscpy.plib import *
|
||||
|
||||
class Deferred(object):
|
||||
def __init__(self, mixin, args):
|
||||
"""
|
||||
"""
|
||||
self.mixin = mixin
|
||||
self.args = args
|
||||
|
||||
def parse(self, scope):
|
||||
"""
|
||||
"""
|
||||
return self.mixin.call(scope, self.args)
|
||||
|
||||
class LessParser(object):
|
||||
precedence = (
|
||||
@@ -82,21 +94,7 @@ class LessParser(object):
|
||||
def scopemap(self):
|
||||
""" Output scopemap.
|
||||
"""
|
||||
if self.result:
|
||||
self._scopemap_aux(self.result)
|
||||
|
||||
def _scopemap_aux(self, ll, lvl=0):
|
||||
pad = ''.join(['\t.'] * lvl)
|
||||
t = type(ll)
|
||||
if t is list:
|
||||
for p in ll:
|
||||
self._scopemap_aux(p, lvl)
|
||||
elif hasattr(ll, 'tokens'):
|
||||
if t is Block:
|
||||
print(pad, ll.name)
|
||||
else:
|
||||
print(pad, t)
|
||||
self._scopemap_aux(list(utility.flatten(ll.tokens)), lvl+1)
|
||||
utility.debug_print(self.result)
|
||||
|
||||
#
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -178,7 +176,8 @@ class LessParser(object):
|
||||
"""
|
||||
try:
|
||||
block = Block(list(p)[1:-1], p.lineno(3))
|
||||
block.parse(self.scope)
|
||||
if not self.scope.in_mixin:
|
||||
block.parse(self.scope)
|
||||
p[0] = block
|
||||
except SyntaxError as e:
|
||||
self.handle_error(e, p.lineno(3))
|
||||
@@ -201,7 +200,7 @@ class LessParser(object):
|
||||
except SyntaxError as e:
|
||||
self.handle_error(e, p.lineno(2))
|
||||
else:
|
||||
self.handle_error('Call unknown mixin `%s`' % p[1], p.lineno(2))
|
||||
self.handle_error('Call unknown block `%s`' % m.raw(), p.lineno(2))
|
||||
|
||||
def p_block_open(self, p):
|
||||
""" block_open : identifier brace_open
|
||||
@@ -224,6 +223,7 @@ class LessParser(object):
|
||||
"""
|
||||
self.scope.add_mixin(Mixin(list(p)[1:], p.lineno(3)).parse(self.scope))
|
||||
self.scope.pop()
|
||||
self.scope.in_mixin = False
|
||||
p[0] = None
|
||||
|
||||
def p_open_mixin(self, p):
|
||||
@@ -231,6 +231,7 @@ class LessParser(object):
|
||||
| id t_popen mixin_args t_pclose brace_open
|
||||
"""
|
||||
p[0] = [p[1][0], p[3]]
|
||||
self.scope.in_mixin = True
|
||||
|
||||
def p_call_mixin(self, p):
|
||||
""" call_mixin : class t_popen mixin_args t_pclose ';'
|
||||
@@ -239,7 +240,10 @@ class LessParser(object):
|
||||
mixin = self.scope.mixins(p[1][0])
|
||||
if mixin:
|
||||
try:
|
||||
p[0] = mixin.call(self.scope, p[3])
|
||||
if self.scope.in_mixin:
|
||||
p[0] = Deferred(mixin, p[3])
|
||||
else:
|
||||
p[0] = mixin.call(self.scope, p[3])
|
||||
except SyntaxError as e:
|
||||
self.handle_error(e, p.lineno(2))
|
||||
else:
|
||||
@@ -309,7 +313,7 @@ class LessParser(object):
|
||||
v.parse(self.scope)
|
||||
self.scope.add_variable(v)
|
||||
except SyntaxError as e:
|
||||
self.handle_error(e, p)
|
||||
self.handle_error(e, p.lineno(2))
|
||||
p[0] = None
|
||||
|
||||
#
|
||||
@@ -702,6 +706,7 @@ class LessParser(object):
|
||||
@param Parser token: Parser token
|
||||
@param string: Error level
|
||||
"""
|
||||
# print(e.trace())
|
||||
if self.verbose:
|
||||
color = '\x1b[31m' if t == 'E' else '\x1b[33m'
|
||||
print("%s%s: line: %d: %s\n" % (color, t, line, e), end='\x1b[0m')
|
||||
|
||||
@@ -7,6 +7,7 @@ class Scope(list):
|
||||
super().__init__()
|
||||
self._mixins = {}
|
||||
if init: self.push()
|
||||
self.in_mixin = False
|
||||
|
||||
def push(self):
|
||||
"""
|
||||
|
||||
@@ -31,7 +31,7 @@ def pairwise(lst):
|
||||
yield lst[i], lst[i+1]
|
||||
yield lst[-1], None
|
||||
|
||||
def rename(ll, fr, scope):
|
||||
def rename(ll, scope):
|
||||
""" Rename all sub-blocks moved under another
|
||||
block. (mixins)
|
||||
"""
|
||||
@@ -40,16 +40,29 @@ def rename(ll, fr, scope):
|
||||
p.name.parse(scope)
|
||||
scope.push()
|
||||
scope.current = p.name
|
||||
if p.inner: rename(p.inner, fr, scope)
|
||||
if p.inner: rename(p.inner, scope)
|
||||
|
||||
def blocksearch(block, name):
|
||||
""" Recursive search for name in block
|
||||
"""
|
||||
for b in block.inner:
|
||||
return (b if b.raw() == name
|
||||
else blocksearch(b, name))
|
||||
b = (b if b.raw() == name
|
||||
else blocksearch(b, name))
|
||||
if b: return b
|
||||
return False
|
||||
|
||||
def debug_print(ll, lvl=0):
|
||||
"""
|
||||
"""
|
||||
pad = ''.join(['\t.'] * lvl)
|
||||
t = type(ll)
|
||||
if t is list:
|
||||
for p in ll:
|
||||
debug_print(p, lvl)
|
||||
elif hasattr(ll, 'tokens'):
|
||||
print(pad, t)
|
||||
debug_print(list(flatten(ll.tokens)), lvl+1)
|
||||
|
||||
def destring(v):
|
||||
""" Strip quotes
|
||||
@param string: value
|
||||
|
||||
@@ -19,13 +19,18 @@ class Block(Node):
|
||||
self.inner = []
|
||||
else:
|
||||
self. inner = [p for p in inner
|
||||
if p and type(p) is type(self)]
|
||||
if p and type(p) is type(self)]
|
||||
if self.inner:
|
||||
self.inner = [p.parse(scope) for p in self.inner]
|
||||
return self
|
||||
|
||||
def raw(self):
|
||||
return self.name.raw()
|
||||
"""
|
||||
"""
|
||||
try:
|
||||
return self.name.raw()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def fmt(self, fills):
|
||||
"""
|
||||
@@ -58,9 +63,9 @@ class Block(Node):
|
||||
"""
|
||||
"""
|
||||
if self.tokens[1]:
|
||||
tokens = copy.deepcopy(self.tokens)
|
||||
tokens = copy.deepcopy(self.tokens[1])
|
||||
scope = copy.deepcopy(scope)
|
||||
out = [p for p in tokens[1] if p]
|
||||
utility.rename(out, self.name, scope)
|
||||
out = [p for p in tokens if p]
|
||||
utility.rename(out, scope)
|
||||
return out
|
||||
return None
|
||||
|
||||
@@ -28,7 +28,9 @@ class Mixin(Node):
|
||||
args = args if type(args) is list else [args]
|
||||
vars = []
|
||||
for arg, var in itertools.zip_longest([a for a in args if a != ','], parsed):
|
||||
if type(var) is Variable:
|
||||
if arg == var and utility.is_variable(arg):
|
||||
continue
|
||||
elif type(var) is Variable:
|
||||
if arg: var.value = arg
|
||||
elif utility.is_variable(arg):
|
||||
tmp = scope.variables(arg)
|
||||
@@ -55,6 +57,13 @@ class Mixin(Node):
|
||||
"""
|
||||
scope = copy.deepcopy(scope)
|
||||
body = copy.deepcopy(self.body)
|
||||
|
||||
self.parse_args(args, scope)
|
||||
scope.update([self.scope], -1)
|
||||
return body.parse(scope).copy(scope)
|
||||
|
||||
body.parse(scope)
|
||||
r = list(utility.flatten([body.parsed, body.inner]))
|
||||
|
||||
utility.rename(r, scope)
|
||||
|
||||
return r
|
||||
|
||||
@@ -106,4 +106,18 @@
|
||||
}
|
||||
.arguments4 {
|
||||
.arguments_empty(1px solid red);
|
||||
}
|
||||
//
|
||||
// filter mixins
|
||||
//
|
||||
.placeholder(@color: #000) {
|
||||
:-moz-placeholder {
|
||||
color: @color;
|
||||
}
|
||||
&::-webkit-input-placeholder {
|
||||
color: @color;
|
||||
}
|
||||
}
|
||||
.div {
|
||||
.placeholder(#fff);
|
||||
}
|
||||
@@ -91,4 +91,4 @@ div.nest {
|
||||
}
|
||||
.secure-zone {
|
||||
#namespace .biohazard .man;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user