Sascha Peilicke 4d63ecfe25 Fix all PEP-8 / flake8 code issues
Drop testscope because it's empty.
2014-02-02 17:35:38 +01:00

232 lines
6.1 KiB
Python

# -*- coding: utf8 -*-
"""
.. module:: lesscpy.plib.call
:synopsis: Call parse node
Copyright (c)
See LICENSE for details.
.. moduleauthor:: Johann T. Mariusson <jtm@robot.is>
"""
import re
import math
try:
from urllib.parse import quote as urlquote
except ImportError:
from urllib import quote as urlquote
from .node import Node
import lesscpy.lessc.utility as utility
import lesscpy.lessc.color as Color
from lesscpy.lib.colors import lessColors
class Call(Node):
"""Call node. Node represents a function call.
All builtin none-color functions are in this node.
This node attempts calls on built-ins and lets non-builtins
through.
increment(3px) --> 4px
unknown(3px) --> unknown(3px)
"""
def parse(self, scope):
"""Parse Node within scope.
the functions ~( and e( map to self.escape
and %( maps to self.sformat
args:
scope (Scope): Current scope
"""
name = ''.join(self.tokens[0])
parsed = self.process(self.tokens[1:], scope)
if name == '%(':
name = 'sformat'
elif name in ('~', 'e'):
name = 'escape'
color = Color.Color()
args = [t for t in parsed
if not isinstance(t, str) or t not in '(),']
if hasattr(self, name):
try:
return getattr(self, name)(*args)
except ValueError:
pass
if hasattr(color, name):
try:
result = getattr(color, name)(*args)
try:
return result + ' '
except TypeError:
return result
except ValueError:
pass
return name + ''.join([p for p in parsed])
def escape(self, string, *args):
"""Less Escape.
args:
string (str): string to escape
returns:
str
"""
return utility.destring(string.strip('~'))
def sformat(self, string, *args):
""" String format.
args:
string (str): string to format
args (list): format options
returns:
str
"""
format = string
items = []
m = re.findall('(%[asdA])', format)
if m and not args:
raise SyntaxError('Not enough arguments...')
i = 0
for n in m:
v = {
'%A': urlquote,
'%s': utility.destring,
}.get(n, str)(args[i])
items.append(v)
i += 1
format = format.replace('%A', '%s')
format = format.replace('%d', '%s')
return format % tuple(items)
def isnumber(self, string, *args):
"""Is number
args:
string (str): match
returns:
bool
"""
try:
n, u = utility.analyze_number(string)
except SyntaxError:
return False
return True
def iscolor(self, string, *args):
"""Is color
args:
string (str): match
returns:
bool
"""
return (string in lessColors)
def isurl(self, string, *args):
"""Is url
args:
string (str): match
returns:
bool
"""
arg = utility.destring(string)
regex = re.compile(r'^(?:http|ftp)s?://' # http:// or https://
r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+'
r'(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' # domain...
# localhost...
r'localhost|'
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
# optional port
r'(?::\d+)?'
r'(?:/?|[/?]\S+)$', re.IGNORECASE)
return regex.match(arg)
def isstring(self, string, *args):
"""Is string
args:
string (str): match
returns:
bool
"""
regex = re.compile(r'\'[^\']*\'|"[^"]*"')
return regex.match(string)
def iskeyword(self, string, *args):
"""Is less keyword
args:
string (str): match
returns:
bool
"""
return (string in ('when', 'and', 'not'))
def increment(self, value, *args):
""" Increment function
args:
value (str): target
returns:
str
"""
n, u = utility.analyze_number(value)
return utility.with_unit(n + 1, u)
def decrement(self, value, *args):
""" Decrement function
args:
value (str): target
returns:
str
"""
n, u = utility.analyze_number(value)
return utility.with_unit(n - 1, u)
def add(self, *args):
""" Add integers
args:
args (list): target
returns:
str
"""
if(len(args) <= 1):
return 0
return sum([int(v) for v in args])
def round(self, value, *args):
""" Round number
args:
value (str): target
returns:
str
"""
n, u = utility.analyze_number(value)
return utility.with_unit(int(utility.away_from_zero_round(float(n))), u)
def ceil(self, value, *args):
""" Ceil number
args:
value (str): target
returns:
str
"""
n, u = utility.analyze_number(value)
return utility.with_unit(int(math.ceil(n)), u)
def floor(self, value, *args):
""" Floor number
args:
value (str): target
returns:
str
"""
n, u = utility.analyze_number(value)
return utility.with_unit(int(math.floor(n)), u)
def percentage(self, value, *args):
""" Return percentage value
args:
value (str): target
returns:
str
"""
n, u = utility.analyze_number(value)
n = int(n * 100.0)
u = '%'
return utility.with_unit(n, u)