summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEevee (Alex Munroe) <eevee.git@veekun.com>2013-08-19 18:18:15 -0700
committerEevee (Alex Munroe) <eevee.git@veekun.com>2013-08-19 18:18:15 -0700
commit1bcfb8a13e051fba190bfa07a48120a0e242134c (patch)
treea8a3f19277c261c44d420e625811e6ad2c6242ed
parent84aef8d2468cf1a4e9deef561bf018835bc79d90 (diff)
downloadpyscss-1bcfb8a13e051fba190bfa07a48120a0e242134c.tar.gz
Add e, pow, log, and sqrt functions from Compass.
-rw-r--r--scss/functions/compass/helpers.py35
-rw-r--r--scss/tests/functions/compass/test_helpers.py21
-rw-r--r--scss/types.py22
3 files changed, 77 insertions, 1 deletions
diff --git a/scss/functions/compass/helpers.py b/scss/functions/compass/helpers.py
index 99e1709..a57616a 100644
--- a/scss/functions/compass/helpers.py
+++ b/scss/functions/compass/helpers.py
@@ -437,6 +437,41 @@ def opposite_position(p):
def pi():
return Number(math.pi)
+
+@register('e', 0)
+def e():
+ return Number(math.e)
+
+
+@register('log', 1)
+@register('log', 2)
+def log(number, base=None):
+ if not isinstance(number, Number):
+ raise TypeError("Expected number, got %r" % (number,))
+ elif not number.is_unitless:
+ raise ValueError("Expected unitless number, got %r" % (number,))
+
+ if base is None:
+ pass
+ elif not isinstance(base, Number):
+ raise TypeError("Expected number, got %r" % (base,))
+ elif not base.is_unitless:
+ raise ValueError("Expected unitless number, got %r" % (base,))
+
+ if base is None:
+ ret = math.log(number.value)
+ else:
+ ret = math.log(number.value, base.value)
+
+ return Number(ret)
+
+
+@register('pow', 2)
+def pow(number, exponent):
+ return number ** exponent
+
+
+COMPASS_HELPERS_LIBRARY.add(Number.wrap_python_function(math.sqrt), 'sqrt', 1)
COMPASS_HELPERS_LIBRARY.add(Number.wrap_python_function(math.sin), 'sin', 1)
COMPASS_HELPERS_LIBRARY.add(Number.wrap_python_function(math.cos), 'cos', 1)
COMPASS_HELPERS_LIBRARY.add(Number.wrap_python_function(math.tan), 'tan', 1)
diff --git a/scss/tests/functions/compass/test_helpers.py b/scss/tests/functions/compass/test_helpers.py
index bb5dfd3..0d52956 100644
--- a/scss/tests/functions/compass/test_helpers.py
+++ b/scss/tests/functions/compass/test_helpers.py
@@ -116,7 +116,26 @@ def test_opposite_position(calc):
## Math
-# pi
+def test_pi(calc):
+ assert calc('pi()') == calc('3.141592653589793')
+
+
+def test_e(calc):
+ assert calc('e()') == calc('2.718281828459045')
+
+
+def test_sqrt(calc):
+ assert calc('sqrt(9)') == calc('3')
+
+
+def test_log(calc):
+ assert calc('log(9, 3)') == calc('2')
+
+
+def test_pow(calc):
+ assert calc('pow(3, 2)') == calc('9')
+ assert calc('pow(10px, 2) / 1px') == calc('100px')
+
# sin
diff --git a/scss/types.py b/scss/types.py
index 2944c71..99ef17c 100644
--- a/scss/types.py
+++ b/scss/types.py
@@ -301,6 +301,28 @@ class Number(Value):
return op(round(left.value, 5), round(right.value, 5))
+ def __pow__(self, exp):
+ if not isinstance(exp, Number):
+ raise TypeError("Can't raise %r to power %r" % (self, exp))
+ if not exp.is_unitless:
+ raise TypeError("Exponent %r cannot have units" % (exp,))
+
+ if self.is_unitless:
+ return Number(self.value ** exp.value)
+
+ # Units can only be exponentiated to integral powers -- what's the
+ # square root of 'px'? (Well, it's sqrt(px), but supporting that is
+ # a bit out of scope.)
+ if exp.value != int(exp.value):
+ raise ValueError("Can't raise units of %r to non-integral power %r" % (self, exp))
+
+ return Number(
+ self.value ** int(exp.value),
+ unit_numer=self.unit_numer * int(exp.value),
+ unit_denom=self.unit_denom * int(exp.value),
+ )
+
+
def __mul__(self, other):
if not isinstance(other, Number):
return NotImplemented