summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/content/en/functions/math.md8
-rw-r--r--tpl/math/init.go18
-rw-r--r--tpl/math/math.go37
-rw-r--r--tpl/math/math_test.go78
4 files changed, 129 insertions, 12 deletions
diff --git a/docs/content/en/functions/math.md b/docs/content/en/functions/math.md
index 58cc5d5db..99b8cf34f 100644
--- a/docs/content/en/functions/math.md
+++ b/docs/content/en/functions/math.md
@@ -1,6 +1,6 @@
---
title: Math
-description: Hugo provides nine mathematical operators in templates.
+description: Hugo provides mathematical operators in templates.
godocref:
date: 2017-02-01
publishdate: 2017-02-01
@@ -35,7 +35,9 @@ aliases: []
| `modBool` | Boolean of modulus of two integers. Evaluates to `true` if result equals 0. | `{{modBool 15 3}}` → `true` |
| `math.Ceil` | Returns the least integer value greater than or equal to the given number. | `{{math.Ceil 2.1}}` → `3` |
| `math.Floor` | Returns the greatest integer value less than or equal to the given number. | `{{math.Floor 1.9}}` → `1` |
-| `math.Round` | Returns the nearest integer, rounding half away from zero. | `{{math.Round 1.5}}` → `2` |
| `math.Log` | Returns the natural logarithm of the given number. | `{{math.Log 42}}` → `3.737` |
-| `math.Sqrt` | Returns the square root of the given number. | `{{math.Sqrt 81}}` → `9` |
+| `math.Max` | Returns the greater of two numbers. | `{{math.Max 1 2}}` → `2` |
+| `math.Min` | Returns the smaller of two numbers. | `{{math.Min 1 2}}` → `1` |
| `math.Pow` | Returns the first number raised to the power of the second number. | `{{math.Pow 2 3}}` → `8` |
+| `math.Round` | Returns the nearest integer, rounding half away from zero. | `{{math.Round 1.5}}` → `2` |
+| `math.Sqrt` | Returns the square root of the given number. | `{{math.Sqrt 81}}` → `9` |
diff --git a/tpl/math/init.go b/tpl/math/init.go
index ddbd2fc73..4d8a23fde 100644
--- a/tpl/math/init.go
+++ b/tpl/math/init.go
@@ -64,10 +64,17 @@ func init() {
},
)
- ns.AddMethodMapping(ctx.Sqrt,
+ ns.AddMethodMapping(ctx.Max,
nil,
[][2]string{
- {"{{math.Sqrt 81}}", "9"},
+ {"{{math.Max 1 2 }}", "2"},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Min,
+ nil,
+ [][2]string{
+ {"{{math.Min 1 2 }}", "1"},
},
)
@@ -106,6 +113,13 @@ func init() {
},
)
+ ns.AddMethodMapping(ctx.Sqrt,
+ nil,
+ [][2]string{
+ {"{{math.Sqrt 81}}", "9"},
+ },
+ )
+
ns.AddMethodMapping(ctx.Sub,
[]string{"sub"},
[][2]string{
diff --git a/tpl/math/math.go b/tpl/math/math.go
index badc189c8..d70a3f833 100644
--- a/tpl/math/math.go
+++ b/tpl/math/math.go
@@ -71,15 +71,28 @@ func (ns *Namespace) Log(a interface{}) (float64, error) {
return math.Log(af), nil
}
-// Sqrt returns the square root of a number.
-// NOTE: will return for NaN for negative values of a
-func (ns *Namespace) Sqrt(a interface{}) (float64, error) {
- af, err := cast.ToFloat64E(a)
- if err != nil {
- return 0, errors.New("Sqrt operator can't be used with non integer or float value")
+// Max returns the greater of two numbers.
+func (ns *Namespace) Max(a, b interface{}) (float64, error) {
+ af, erra := cast.ToFloat64E(a)
+ bf, errb := cast.ToFloat64E(b)
+
+ if erra != nil || errb != nil {
+ return 0, errors.New("Max operator can't be used with non-float value")
}
- return math.Sqrt(af), nil
+ return math.Max(af, bf), nil
+}
+
+// Min returns the smaller of two numbers.
+func (ns *Namespace) Min(a, b interface{}) (float64, error) {
+ af, erra := cast.ToFloat64E(a)
+ bf, errb := cast.ToFloat64E(b)
+
+ if erra != nil || errb != nil {
+ return 0, errors.New("Min operator can't be used with non-float value")
+ }
+
+ return math.Min(af, bf), nil
}
// Mod returns a % b.
@@ -135,6 +148,16 @@ func (ns *Namespace) Round(x interface{}) (float64, error) {
return _round(xf), nil
}
+// Sqrt returns the square root of a number.
+func (ns *Namespace) Sqrt(a interface{}) (float64, error) {
+ af, err := cast.ToFloat64E(a)
+ if err != nil {
+ return 0, errors.New("Sqrt operator can't be used with non integer or float value")
+ }
+
+ return math.Sqrt(af), nil
+}
+
// Sub subtracts two numbers.
func (ns *Namespace) Sub(a, b interface{}) (interface{}, error) {
return _math.DoArithmetic(a, b, '-')
diff --git a/tpl/math/math_test.go b/tpl/math/math_test.go
index da59d7938..45f28e093 100644
--- a/tpl/math/math_test.go
+++ b/tpl/math/math_test.go
@@ -357,3 +357,81 @@ func TestPow(t *testing.T) {
c.Assert(result, qt.Equals, test.expect)
}
}
+
+func TestMax(t *testing.T) {
+ t.Parallel()
+ c := qt.New(t)
+
+ ns := New()
+
+ for _, test := range []struct {
+ a interface{}
+ b interface{}
+ expect interface{}
+ }{
+ {-1, -1, float64(-1)},
+ {-1, 0, float64(0)},
+ {-1, 1, float64(1)},
+ {0, -1, float64(0)},
+ {0, 0, float64(0)},
+ {0, 1, float64(1)},
+ {1, -1, float64(1)},
+ {1, 0, float64(1)},
+ {1, 1, float64(1)},
+ {1.2, 1.23, float64(1.23)},
+ {-1.2, -1.23, float64(-1.2)},
+ {0, "a", false},
+ {"a", 0, false},
+ {"a", "b", false},
+ } {
+
+ result, err := ns.Max(test.a, test.b)
+
+ if b, ok := test.expect.(bool); ok && !b {
+ c.Assert(err, qt.Not(qt.IsNil))
+ continue
+ }
+
+ c.Assert(err, qt.IsNil)
+ c.Assert(result, qt.Equals, test.expect)
+ }
+}
+
+func TestMin(t *testing.T) {
+ t.Parallel()
+ c := qt.New(t)
+
+ ns := New()
+
+ for _, test := range []struct {
+ a interface{}
+ b interface{}
+ expect interface{}
+ }{
+ {-1, -1, float64(-1)},
+ {-1, 0, float64(-1)},
+ {-1, 1, float64(-1)},
+ {0, -1, float64(-1)},
+ {0, 0, float64(0)},
+ {0, 1, float64(0)},
+ {1, -1, float64(-1)},
+ {1, 0, float64(0)},
+ {1, 1, float64(1)},
+ {1.2, 1.23, float64(1.2)},
+ {-1.2, -1.23, float64(-1.23)},
+ {0, "a", false},
+ {"a", 0, false},
+ {"a", "b", false},
+ } {
+
+ result, err := ns.Min(test.a, test.b)
+
+ if b, ok := test.expect.(bool); ok && !b {
+ c.Assert(err, qt.Not(qt.IsNil))
+ continue
+ }
+
+ c.Assert(err, qt.IsNil)
+ c.Assert(result, qt.Equals, test.expect)
+ }
+}