Exemplo n.º 1
0
 def parse(self, scope):
     """Parse node
     args:
         scope (Scope): current scope
     raises:
         SyntaxError
     returns:
         self
     """
     self.name, args, self.guards = self.tokens[0]
     self.args = [a for a in utility.flatten(args) if a]
     self.body = Block([None, self.tokens[1]], 0)
     self.vars = list(utility.flatten([list(v.values()) for v in [s["__variables__"] for s in scope]]))
     return self
Exemplo n.º 2
0
 def process(self, tokens, scope):
     """ Process tokenslist, flattening and parsing it
     args:
         tokens (list): tokenlist
         scope (Scope): Current scope
     returns:
         list
     """
     while True:
         tokens = list(utility.flatten(tokens))
         done = True
         if any(t for t in tokens if hasattr(t, 'parse')):
             tokens = [
                 t.parse(scope) if hasattr(t, 'parse') else t
                 for t in tokens
             ]
             done = False
         if any(
                 t for t in tokens
                 if (utility.is_variable(t)) or str(type(t)) ==
                 "<class 'lesscpy.plib.variable.Variable'>"):
             tokens = self.replace_variables(tokens, scope)
             done = False
         if done:
             break
     return tokens
Exemplo n.º 3
0
 def parse(self, scope):
     """Parse node
     args:
         scope (Scope): current scope
     raises:
         SyntaxError
     returns:
         self
     """
     self.name, args, self.guards = self.tokens[0]
     self.args = [a for a in utility.flatten(args) if a]
     self.body = Block([None, self.tokens[1]], 0)
     self.vars = list(
         utility.flatten([
             list(v.values()) for v in [s['__variables__'] for s in scope]
         ]))
     return self
Exemplo n.º 4
0
 def parse(self, scope):
     """Parse node. Block identifiers are stored as
     strings with spaces replaced with ?
     args:
         scope (Scope): Current scope
     raises:
         SyntaxError
     returns:
         self
     """
     names       = []
     name        = []
     self._subp  = (
         '@media', '@keyframes', 
         '@-moz-keyframes', '@-webkit-keyframes',
         '@-ms-keyframes'
     )
     if self.tokens and hasattr(self.tokens, 'parse'):
         self.tokens = list(utility.flatten([id.split() + [','] 
                                             for id in self.tokens.parse(scope).split(',')]))
         self.tokens.pop()
     if self.tokens and self.tokens[0] in self._subp:
         name = list(utility.flatten(self.tokens))
         self.subparse = True
     else:
         self.subparse = False
         for n in utility.flatten(self.tokens):
             if n == '*':
                 name.append('* ')
             elif n in '>+~':
                 if name and name[-1] == ' ':
                     name.pop()
                 name.append('?%s?' % n)
             elif n == ',':
                 names.append(name)
                 name = []
             else:
                 name.append(n)
     names.append(name)
     parsed = self.root(scope, names) if scope else names
     self.parsed = [[i for i, j in utility.pairwise(part) 
                     if i != ' ' or (j and '?' not in j)] 
                    for part in parsed]
     return self
Exemplo n.º 5
0
 def swap(self, var):
     """ Replace variable
     args:
         var (str): variable
     raises:
         SyntaxError
     returns:
         str
     """
     var = self.scope.swap('@' + var)
     var = ''.join(utility.flatten(var))
     return var.strip("\"'")
Exemplo n.º 6
0
 def parse(self, scope):
     """Parse node
     args:
         scope (Scope): current scope
     raises:
         SyntaxError
     returns:
         self
     """
     self.name, args, self.guards = self.tokens[0]
     self.args = [a for a in utility.flatten(args) if a]
     self.body = Block([None, self.tokens[1]], 0)
     self.scope = copy.deepcopy(scope[-1])
     return self
Exemplo n.º 7
0
 def parse(self, scope):
     """Parse node. Block identifiers are stored as
     strings with spaces replaced with ?
     args:
         scope (Scope): Current scope
     raises:
         SyntaxError
     returns:
         self
     """
     names = []
     name = []
     self._subp = ("@media", "@keyframes", "@-moz-keyframes", "@-webkit-keyframes", "@-ms-keyframes")
     if self.tokens and hasattr(self.tokens, "parse"):
         self.tokens = list(utility.flatten([id.split() + [","] for id in self.tokens.parse(scope).split(",")]))
         self.tokens.pop()
     if self.tokens and self.tokens[0] in self._subp:
         name = list(utility.flatten(self.tokens))
         self.subparse = True
     else:
         self.subparse = False
         for n in utility.flatten(self.tokens):
             if n == "*":
                 name.append("* ")
             elif n in ">+~":
                 if name and name[-1] == " ":
                     name.pop()
                 name.append("?%s?" % n)
             elif n == ",":
                 names.append(name)
                 name = []
             else:
                 name.append(n)
     names.append(name)
     parsed = self.root(scope, names) if scope else names
     self.parsed = [[i for i, j in utility.pairwise(part) if i != " " or (j and "?" not in j)] for part in parsed]
     return self
Exemplo n.º 8
0
 def parse(self, scope):
     """Parse node
     args:
         scope (Scope): current scope
     raises:
         SyntaxError
     returns:
         self
     """
     self.parsed = list(utility.flatten(self.tokens))
     if self.parsed[0] == '@import':
         if len(self.parsed) > 4:
             # Media @import
             self.parsed.insert(3, ' ')
     return self
Exemplo n.º 9
0
 def parse(self, scope):
     """Parse node
     args:
         scope (Scope): current scope
     raises:
         SyntaxError
     returns:
         self
     """
     self.parsed = list(utility.flatten(self.tokens))
     if self.parsed[0] == '@import':
         if len(self.parsed) > 4:
             # Media @import
             self.parsed.insert(3, ' ')
     return self
Exemplo n.º 10
0
 def parse(self, scope):
     """Parse block node.
     args:
         scope (Scope): Current scope
     raises:
         SyntaxError
     returns:
         self
     """
     if not self.parsed:
         scope.push()
         self.name, inner = self.tokens
         scope.current = self.name
         if not self.name.parsed:
             self.name.parse(scope)
         if not inner:
             inner = []
         inner = list(utility.flatten([p.parse(scope) for p in inner if p]))
         self.parsed = [p for p in inner if p and type(p) is not Block]
         self.inner = [p for p in inner if p and type(p) is Block]
         scope.pop()
     return self
Exemplo n.º 11
0
 def parse(self, scope):
     """Parse block node.
     args:
         scope (Scope): Current scope
     raises:
         SyntaxError
     returns:
         self
     """
     if not self.parsed:
         scope.push()
         self.name, inner = self.tokens
         scope.current = self.name
         scope.real.append(self.name)
         if not self.name.parsed:
             self.name.parse(scope)
         if not inner:
             inner = []
         inner = list(utility.flatten([p.parse(scope) for p in inner if p]))
         self.parsed = [p for p in inner if p and not isinstance(p, Block)]
         self.inner = [p for p in inner if p and isinstance(p, Block)]
         scope.real.pop()
         scope.pop()
     return self
Exemplo n.º 12
0
 def process(self, tokens, scope):
     """ Process tokenslist, flattening and parsing it
     args:
         tokens (list): tokenlist
         scope (Scope): Current scope
     returns:
         list
     """
     while True:
         tokens = list(utility.flatten(tokens))
         done = True
         if any(t for t in tokens if hasattr(t, 'parse')):
             tokens = [
                 t.parse(scope) if hasattr(t, 'parse') else t
                 for t in tokens
             ]
             done = False
         if any(t for t in tokens if (utility.is_variable(t)) or str(type(
                 t)) == "<class 'lesscpy.plib.variable.Variable'>"):
             tokens = self.replace_variables(tokens, scope)
             done = False
         if done:
             break
     return tokens
Exemplo n.º 13
0
    def parse(self, scope):
        """Parse node. Block identifiers are stored as
        strings with spaces replaced with ?
        args:
            scope (Scope): Current scope
        raises:
            SyntaxError
        returns:
            self
        """
        names = []
        name = []
        self._subp = (
            '@media', '@keyframes',
            '@-moz-keyframes', '@-webkit-keyframes',
            '@-ms-keyframes'
        )
        if self.tokens and hasattr(self.tokens, 'parse'):
            self.tokens = list(utility.flatten([id.split() + [',']
                                                for id in self.tokens.parse(scope).split(',')]))
            self.tokens.pop()
        if self.tokens and any(hasattr(t, 'parse') for t in self.tokens):
            tmp_tokens = []
            for t in self.tokens:
                if hasattr(t, 'parse'):
                    tmp_tokens.append(t.parse(scope))
                else:
                    tmp_tokens.append(t)
            self.tokens = list(utility.flatten(tmp_tokens))
        if self.tokens and self.tokens[0] in self._subp:
            name = list(utility.flatten(self.tokens))
            self.subparse = True
        else:
            self.subparse = False
            for n in utility.flatten(self.tokens):
                if n == '*':
                    name.append('* ')
                elif n in '>+~':
                    if name and name[-1] == ' ':
                        name.pop()
                    name.append('?%s?' % n)
                elif n == ',':
                    names.append(name)
                    name = []
                else:
                    name.append(n)
        names.append(name)
        parsed = self.root(scope, names) if scope else names

        # Interpolated selectors need another step, we have to replace variables. Avoid reserved words though
        #
        # Example:  '.@{var}'       results in [['.', '@{var}']]
        # But:      '@media print'  results in [['@media', ' ', 'print']]
        #
        def replace_variables(tokens, scope):
            return [scope.swap(t)
                    if (utility.is_variable(t) and not t in reserved.tokens)
                    else t
                    for t in tokens]
        parsed = [list(utility.flatten(replace_variables(part, scope))) for part in parsed]

        self.parsed = [[i for i, j in utility.pairwise(part)
                        if i != ' ' or (j and '?' not in j)]
                       for part in parsed]
        return self
Exemplo n.º 14
0
 def parse(self, scope):
     """Parse block node.
     args:
         scope (Scope): Current scope
     raises:
         SyntaxError
     returns:
         self
     """
     if not self.parsed:
         scope.push()
         self.name, inner = self.tokens
         scope.current = self.name
         scope.real.append(self.name)
         if not self.name.parsed:
             self.name.parse(scope)
         if not inner:
             inner = []
         inner = list(utility.flatten([p.parse(scope) for p in inner if p]))
         self.parsed = []
         self.inner = []
         if not hasattr(self, "inner_media_queries"):
             self.inner_media_queries = []
         for p in inner:
             if p is not None:
                 if isinstance(p, Block):
                     if len(scope) == 2 and p.tokens[1] is not None:
                         p_is_mediaquery = p.name.tokens[0] == '@media'
                         # Inner block @media ... { ... } is a nested media
                         # query. But double-nested media queries have to be
                         # removed and marked as well. While parsing ".foo",
                         # both nested "@media print" and double-nested
                         # "@media all" will be handled as we have to
                         # re-arrange the scope and block layout quite a bit:
                         #
                         #   .foo {
                         #       @media print {
                         #           color: blue;
                         #           @media screen { font-size: 12em; }
                         #       }
                         #   }
                         #
                         # Expected result:
                         #
                         #   @media print {
                         #       .foo { color: blue; }
                         #   }
                         #   @media print and screen {
                         #       .foo { font-size: 12 em; }
                         #   }
                         append_list = []
                         reparse_p = False
                         for child in p.tokens[1]:
                             if isinstance(child, Block) and child.name.raw(
                             ).startswith("@media"):
                                 # Remove child from the nested media query, it will be re-added to
                                 # the parent with 'merged' media query (see above example).
                                 p.tokens[1].remove(child)
                                 if p_is_mediaquery:  # Media query inside a & block
                                     # Double-nested media query found. We remove it from 'p' and add
                                     # it to this block with a new 'name'.
                                     reparse_p = True
                                     part_a = p.name.tokens[2:][0][0][0]
                                     part_b = child.name.tokens[2:][0][0]
                                     new_ident_tokens = [
                                         '@media', ' ',
                                         [
                                             part_a, (' ', 'and', ' '),
                                             part_b
                                         ]
                                     ]
                                     # Parse child again with new @media $BLA {} part
                                     child.tokens[0] = Identifier(
                                         new_ident_tokens)
                                     child.parsed = None
                                     child = child.parse(scope)
                                 else:
                                     child.block_name = p.name
                                 append_list.append(child)
                             if reparse_p:
                                 p.parsed = None
                                 p = p.parse(scope)
                         if not p_is_mediaquery and not append_list:
                             self.inner.append(p)
                         else:
                             append_list.insert(
                                 0, p
                             )  # This media query should occur before it's children
                             for media_query in append_list:
                                 self.inner_media_queries.append(
                                     media_query)
                         # NOTE(saschpe): The code is not recursive but we hope that people
                         # wont use triple-nested media queries.
                     else:
                         self.inner.append(p)
                 else:
                     self.parsed.append(p)
         if self.inner_media_queries:
             # Nested media queries, we have to remove self from scope and
             # push all nested @media ... {} blocks.
             scope.remove_block(self, index=-2)
             for mb in self.inner_media_queries:
                 # New inner block with current name and media block contents
                 if hasattr(mb, 'block_name'):
                     cb_name = mb.block_name
                 else:
                     cb_name = self.tokens[0]
                 cb = Block([cb_name, mb.tokens[1]]).parse(scope)
                 # Replace inner block contents with new block
                 new_mb = Block([mb.tokens[0], [cb]]).parse(scope)
                 self.inner.append(new_mb)
                 scope.add_block(new_mb)
         scope.real.pop()
         scope.pop()
     return self
Exemplo n.º 15
0
 def expression(self):
     """Return str representation of expression
     returns:
         str
     """
     return utility.flatten(self.tokens)
    def parse(self, scope):
        """Parse node. Block identifiers are stored as
        strings with spaces replaced with ?
        args:
            scope (Scope): Current scope
        raises:
            SyntaxError
        returns:
            self
        """
        names = []
        name = []
        self._subp = ('@media', '@keyframes', '@-moz-keyframes',
                      '@-webkit-keyframes', '@-ms-keyframes')
        if self.tokens and hasattr(self.tokens, 'parse'):
            self.tokens = list(
                utility.flatten([
                    id.split() + [',']
                    for id in self.tokens.parse(scope).split(',')
                ]))
            self.tokens.pop()
        if self.tokens and any(hasattr(t, 'parse') for t in self.tokens):
            tmp_tokens = []
            for t in self.tokens:
                if hasattr(t, 'parse'):
                    tmp_tokens.append(t.parse(scope))
                else:
                    tmp_tokens.append(t)
            self.tokens = list(utility.flatten(tmp_tokens))
        if self.tokens and self.tokens[0] in self._subp:
            name = list(utility.flatten(self.tokens))
            self.subparse = True
        else:
            self.subparse = False
            for n in utility.flatten(self.tokens):
                if n == '*':
                    name.append('* ')
                elif n in '>+~':
                    if name and name[-1] == ' ':
                        name.pop()
                    name.append('?%s?' % n)
                elif n == ',':
                    names.append(name)
                    name = []
                else:
                    name.append(n)
        names.append(name)
        parsed = self.root(scope, names) if scope else names

        # Interpolated selectors need another step, we have to replace variables. Avoid reserved words though
        #
        # Example:  '.@{var}'       results in [['.', '@{var}']]
        # But:      '@media print'  results in [['@media', ' ', 'print']]
        #
        def replace_variables(tokens, scope):
            return [
                scope.swap(t) if
                (utility.is_variable(t) and not t in reserved.tokens) else t
                for t in tokens
            ]

        parsed = [
            list(utility.flatten(replace_variables(part, scope)))
            for part in parsed
        ]

        self.parsed = [[
            i for i, j in utility.pairwise(part)
            if i != ' ' or (j and '?' not in j)
        ] for part in parsed]
        return self
Exemplo n.º 17
0
 def parse(self, scope):
     """Parse block node.
     args:
         scope (Scope): Current scope
     raises:
         SyntaxError
     returns:
         self
     """
     if not self.parsed:
         scope.push()
         self.name, inner = self.tokens
         scope.current = self.name
         scope.real.append(self.name)
         if not self.name.parsed:
             self.name.parse(scope)
         if not inner:
             inner = []
         inner = list(utility.flatten([p.parse(scope) for p in inner if p]))
         self.parsed = []
         self.inner = []
         if not hasattr(self, "inner_media_queries"):
             self.inner_media_queries = []
         for p in inner:
             if p is not None:
                 if isinstance(p, Block):
                     if (len(scope) == 2 and p.tokens[1] is not None):
                         p_is_mediaquery = p.name.tokens[0] == '@media'
                         # Inner block @media ... { ... } is a nested media
                         # query. But double-nested media queries have to be
                         # removed and marked as well. While parsing ".foo",
                         # both nested "@media print" and double-nested
                         # "@media all" will be handled as we have to
                         # re-arrange the scope and block layout quite a bit:
                         #
                         #   .foo {
                         #       @media print {
                         #           color: blue;
                         #           @media screen { font-size: 12em; }
                         #       }
                         #   }
                         #
                         # Expected result:
                         #
                         #   @media print {
                         #       .foo { color: blue; }
                         #   }
                         #   @media print and screen {
                         #       .foo { font-size: 12 em; }
                         #   }
                         append_list = []
                         reparse_p = False
                         for child in p.tokens[1]:
                             if isinstance(child, Block) and child.name.raw().startswith("@media"):
                                 # Remove child from the nested media query, it will be re-added to
                                 # the parent with 'merged' media query (see above example).
                                 p.tokens[1].remove(child)
                                 if p_is_mediaquery:  # Media query inside a & block
                                     # Double-nested media query found. We remove it from 'p' and add
                                     # it to this block with a new 'name'.
                                     reparse_p = True
                                     part_a = p.name.tokens[2:][0][0][0]
                                     part_b = child.name.tokens[2:][0][0]
                                     new_ident_tokens = ['@media', ' ', [part_a, (' ', 'and', ' '), part_b]]
                                     # Parse child again with new @media $BLA {} part
                                     child.tokens[0] = Identifier(new_ident_tokens)
                                     child.parsed = None
                                     child = child.parse(scope)
                                 else:
                                     child.block_name = p.name
                                 append_list.append(child)
                             if reparse_p:
                                 p.parsed = None
                                 p = p.parse(scope)
                         if not p_is_mediaquery and not append_list:
                             self.inner.append(p)
                         else:
                             append_list.insert(0, p)  # This media query should occur before it's children
                             for media_query in append_list:
                                 self.inner_media_queries.append(media_query)
                         # NOTE(saschpe): The code is not recursive but we hope that people
                         # wont use triple-nested media queries.
                     else:
                         self.inner.append(p)
                 else:
                     self.parsed.append(p)
         if self.inner_media_queries:
             # Nested media queries, we have to remove self from scope and
             # push all nested @media ... {} blocks.
             scope.remove_block(self, index=-2)
             for mb in self.inner_media_queries:
                 # New inner block with current name and media block contents
                 if hasattr(mb, 'block_name'):
                     cb_name = mb.block_name
                 else:
                     cb_name = self.tokens[0]
                 cb = Block([cb_name, mb.tokens[1]]).parse(scope)
                 # Replace inner block contents with new block
                 new_mb = Block([mb.tokens[0], [cb]]).parse(scope)
                 self.inner.append(new_mb)
                 scope.add_block(new_mb)
         scope.real.pop()
         scope.pop()
     return self