def test_parser_parse_basic(): parser = Parser("abc\n color: red\n", {}) root = parser.parse() assert root.node_name == "root" assert root.nodes[0].node_name == "group" selector = root.nodes[0].nodes[0] assert selector.segments[0] == Literal("abc") assert selector.block.parent == root assert selector.block.node.node_name == "group" property = selector.block.nodes[0] assert property.node_name == "property" assert len(property.segments) == 1 assert property.segments[0] == Ident("color", null, lineno=2, column=3) assert len(property.expr.nodes) == 1 assert property.expr.nodes[0] == Ident("red", null, lineno=2, column=10)
def test_evaluator_create(): parser = Parser("abc\n color: red\n", {}) root = parser.parse() evaluator = Evaluator(root, parser=parser, options={}) result = evaluator.evaluate() assert result.node_name == "root" assert result.nodes[0].node_name == "group" assert result.nodes[0].nodes[0].node_name == "selector" assert result.nodes[0].nodes[0].block.node_name == "block" assert result.nodes[0].nodes[0].block.nodes[0].node_name == "property" property = result.nodes[0].nodes[0].block.nodes[0] assert property.expr.node_name == "expression" assert property.expr.nodes[0].r == 255 assert property.expr.nodes[0].name == "red" assert property.expr.nodes[0].a == 1 assert property.expr.nodes[0].b == 0 assert property.expr.nodes[0].g == 0
def mixin_object(self, object: ObjectNode): s = f"$block {object.to_block()}" p = Parser(s, utils.merge({"root": Root()}, self.options)) try: block = p.parse() except StilusError as e: e.filename = self.filename e.lineno = p.lexer.lineno e.column = p.lexer.column e.input = s raise e block.parent = self.root block.scope = False ret = self.visit(block) values = ret.first().nodes for value in values: if value.block: self.mixin(value.block.nodes, self.get_current_block()) break
def import_file(self, node: Import, file, literal, lineno=1, column=1): log.debug(f"importing {file}; {self.import_stack}") # handling 'require' if node.once: if self.require_history.get(file, False): return null self.require_history[file] = True if literal and not self.include_css: return node # avoid overflows from reimporting the same file if file in self.import_stack: raise ImportError("import loop has been found") with open(file, "r") as f: source = f.read() # shortcut for empty files if not source.strip(): return null # expose imports node.path = file node.dirname = Path(file).parent # store modified time node.mtime = os.stat(file).st_mtime self.paths.append(str(node.dirname)) if "_imports" in self.options: self.options["_imports"].append(node.clone()) # parse the file self.import_stack.append(file) filename_node.current_filename = file if literal: re.sub("\n\n?", "\n", source) literal = Literal(source, lineno=self.parser.lineno, column=self.parser.column) literal.lineno = 1 literal.column = 1 if not self.resolve_url: return literal # create block block = Block(None, None, lineno=lineno, column=column) block.filename = file # parse merged = {} merged.update(self.options) merged.update({"root": block}) parser = Parser(source, merged) try: block = parser.parse() except Exception: line = parser.lexer.lineno column = parser.lexer.column if literal and self.include_css and self.resolve_url: self.warn(f"ParseError: {file}:{line}:{column}. " f"This file is included as-is") return literal else: raise ParseError( "Issue when parsing an imported file", filename=file, lineno=line, column=column, input=source, ) # evaluate imported 'root' block = block.clone(self.get_current_block()) block.parent = self.get_current_block() block.scope = False ret = self.visit(block) self.import_stack.pop() if not self.resolve_url: # or not self.resolve_url no_check: self.paths.pop() return ret