Ejemplo n.º 1
0
Archivo: adjust.py Proyecto: jw/stilus
def adjust(color, prop, amount, evaluator=None):
    assert_color(color, "color")
    assert_string(prop, "prop")
    assert_type(amount, "unit", "amount")
    hsl = color.hsla().clone()
    if not hasattr(hsl, prop.string):
        raise StilusError("Invalid adjustment property.")
    value = amount.value
    if amount.type == "%":
        if prop.string == "lightness" and value > 0:
            value = (100 - hsl.lightness) * value / 100
        else:
            value = getattr(hsl, prop.string) * (value / 100)
    setattr(hsl, prop.string, getattr(hsl, prop.string) + value)
    return hsl.rgba()
Ejemplo n.º 2
0
def range_function(start, stop, step=None, evaluator=None):
    assert_type(start, "unit", "start")
    assert_type(stop, "unit", "stop")
    if step:
        assert_type(step, "unit", "step")
        if step.value == 0:
            raise StilusError('ArgumentError: "step" argument '
                              "must not be zero")
    else:
        step = Unit(1)
    lst = Expression()
    i = start.value
    while i <= stop.value:
        lst.append(Unit(i, start.type))
        i += step.value
    return lst
Ejemplo n.º 3
0
def image_size(img: str, ignore_errors=False, evaluator=None):
    assert_type(img, "string", "img")
    p = Path(img.string)
    path = lookup(p, evaluator.paths)
    if p.suffix == ".svg":
        return _x_and_y_from_svg(path)
    if path:
        with Image.open(path) as image:
            x, y = image.size
            expression = Expression()
            expression.nodes = [Unit(x, "px"), Unit(y, "px")]
            return expression
    elif ignore_errors:
        expression = Expression()
        expression.nodes = [Unit(0), Unit(0)]
        return expression
    else:
        raise StilusError("Could not find image.")
Ejemplo n.º 4
0
 def visit(self, node):
     try:
         return super().visit(node)
     except StilusError as se:
         if not se.filename:
             raise se
         try:
             with open(str(se.filename)) as f:
                 input = f.read()
         except (AttributeError, FileNotFoundError):
             pass
         raise StilusError(
             self.stack,
             filename=node.filename,
             lineno=node.lineno,
             column=node.column,
             input=input,
         )
Ejemplo n.º 5
0
def opposite_position(positions, evaluator=None):
    expr = []
    nodes = utils.unwrap(positions)
    for i, node in enumerate(nodes):
        utils.assert_string(node, f"position {i}")
        if node.string == "top":
            expr.append(Literal("bottom"))
        elif node.string == "bottom":
            expr.append(Literal("top"))
        elif node.string == "left":
            expr.append(Literal("right"))
        elif node.string == "right":
            expr.append(Literal("left"))
        elif node.string == "center":
            expr.append(Literal("center"))
        else:
            raise StilusError(f"invalid position {i}")
    return expr
Ejemplo n.º 6
0
    def visit_group(self, group: Group):
        if self.keyframe:
            stack = []
        else:
            stack = self.stack

        if self.compress:
            comma = ","
        else:
            comma = ",\n"

        stack.append(group.nodes)

        # selectors
        if group.block.has_properties():
            selectors = utils.compile_selectors(
                stack, leave_hidden=False, indent=self.indent()
            )

            if selectors:
                if self.keyframe:
                    if self.compress:
                        comma = ","
                    else:
                        comma = ", "

                for i, selector in enumerate(selectors):
                    last = i == len(selectors) - 1

                    # keyframe bocks (10%, 20% { ... })
                    if self.keyframe:
                        selector = selector.strip() if i else selector
                    try:
                        self.buf += self.out(
                            selector + ("" if last else comma)
                        )
                    except BaseException:
                        raise StilusError()
            else:
                group.block.lacks_rendered_selectors = True

        self.visit(group.block)
        stack.pop()
Ejemplo n.º 7
0
def json_function(path, local=None, name_prefix=None, evaluator=None):
    assert_string(path, "path")

    def convert(content, options):
        ret = ObjectNode()
        leave_strings = options.get("leave-strings").to_boolean()
        for key in content:
            val = content[key]
            if isinstance(val, dict):
                ret.set(key, convert(val, options))
            else:
                val = coerce(val, raw=False)
                if (val and val.node_name == "string"
                        and leave_strings.is_false()):
                    val = parse_string(val.string)
                ret.set(key, val)
        return ret

    # lookup
    path = path.string
    found = lookup(path, evaluator.paths, evaluator.filename)
    options = None
    if (local and hasattr(local, "node_name")
            and local.node_name == "objectnode"):
        options = local

    if not found:
        if options:
            optional = options.get("optional")
            if optional and optional.first().is_true():
                return null
        raise StilusError(f"failed to locate .json file {path}")

    # read
    with open(found, "r") as reader:
        content = json.load(reader)

    if options:
        return convert(content, options)
    else:
        old_json_function(content, local, name_prefix, evaluator)
Ejemplo n.º 8
0
def error(msg, evaluator=None):
    assert_type(msg, "string", "msg")
    err = StilusError(msg.value)
    err.from_stilus = True
    raise err
Ejemplo n.º 9
0
    def visit_import(self, imported):
        literal = False
        self.result += 1

        path = self.visit(imported.path).first()

        node_name = "require" if imported.once else "import"

        self.result -= 1

        log.debug(f"import {path}")

        # url() passed
        if hasattr(path, "function_name") and path.function_name == "url":
            if hasattr(imported, "once") and imported.once:
                raise StilusError("You cannot @require a url")
            return imported

        # ensure string
        if not hasattr(path, "string"):
            raise StilusError(f"@{node_name} string expected")

        name = path = path.string

        # absolute URL or hash
        m = re.match(r"(?:url\s*\(\s*)?[\'\"]?(?:#|(?:https?:)?\/\/)", path,
                     re.I)
        if m:
            if imported.once:
                raise StilusError("You cannot @require a url")
            return imported

        # literal
        if path.endswith(".css") or '.css"' in path:
            literal = True
            if not imported.once and not self.include_css:
                return imported

        # support optional .styl
        if not literal and not path.endswith(".styl"):
            path += ".styl"

        # lookup
        found = utils.find(path, self.paths, self.filename)
        if not found:
            found = utils.lookup_index(name,
                                       self.paths,
                                       self.filename,
                                       parser=self.parser)

        # throw if import failed
        if not found:
            raise TypeError(f"failed to locate @{node_name} file in {path}"
                            f" {self.paths}")

        block = Block(None,
                      None,
                      lineno=self.parser.lineno,
                      column=self.parser.column)
        for f in found:
            block.append(
                self.import_file(
                    imported,
                    f,
                    literal,
                    lineno=self.parser.lineno,
                    column=self.parser.column,
                ))

        return block
Ejemplo n.º 10
0
Archivo: node.py Proyecto: jw/stilus
    def operate(  # noqa: C901
        self, op: str, right: Type["Node"], value=None
    ) -> "Node":
        """Operate on ``right`` with the given ``op``."""
        from .boolean import Boolean

        if op == "is a":
            if "string" == right.first().node_name:
                return Boolean(self.node_name == right.value)
            else:
                raise Exception(
                    f'"is a" expects a string, ' f"got {right.toString}"
                )
        elif op == "==":
            from stilus import utils

            if utils.is_number(self) and utils.is_number(right):
                return Boolean(utils.get_value(self) == utils.get_value(right))
            return Boolean(self.hash() == right.hash())
        elif op == "!=":
            return Boolean(self.hash() != right.hash())
        elif op == ">=":
            return Boolean(self.hash() >= right.hash())
        elif op == "<=":
            return Boolean(self.hash() <= right.hash())
        elif op == ">":
            if self.one_is_unit(right):
                return Boolean(float(self.hash()) > float(right.hash()))
            return Boolean(self.hash() > right.hash())
        elif op == "<":
            return Boolean(self.hash() < right.hash())
        elif op == "||":
            return self if self.to_boolean().value is True else right
        elif op == "in":
            from stilus import utils

            values = utils.unwrap(right).nodes
            if not values:
                raise StilusError(
                    '"in" given invalid right-hand operand, '
                    "expecting an expression"
                )

            # 'prop' in object
            if len(values) == 1 and values[0].node_name == "objectnode":
                return Boolean(values[0].has(self.hash()))

            for value in values:
                if str(value.hash()) == str(self.hash()):
                    return Boolean(True)

            return Boolean(False)
        elif op == "&&":
            a = self.to_boolean()
            b = right.to_boolean()
            if a.value is True and b.value is True:
                return right
            elif a.value is False:
                return self
            return right
        elif op == "[]":
            raise StilusError(f"cannot perform {self}[{right}]")
        else:
            raise StilusError(f"cannot perform {self} {op} {right}")