Edd Salkield: 2 funcs.go: Add mathematical functions docs: Document mathematical functions 2 files changed, 321 insertions(+), 0 deletions(-)
Pushed with minor edits. Thanks! If you have some time, it might be nice to add some tests for these new math functions in a new file funcs_test.go. To git@git.sr.ht:~adnano/kiln 4f73b34..4e6a81e master -> master
Thanks for your help getting this implemented. I'll take a look at writing some tests next time I have a bit of time.
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~adnano/kiln-devel/patches/33457/mbox | git am -3Learn more about email & git
--- funcs.go | 279 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) diff --git a/funcs.go b/funcs.go index 2704ebe..54082ba 100644 --- a/funcs.go +++ b/funcs.go @@ -2,6 +2,7 @@ package main import ( "html/template" + "math" "path" "reflect" "strings" @@ -13,6 +14,7 @@ import ( func (s *Site) funcs() map[string]interface{} { return map[string]interface{}{ "exec": executeString, + "math": func() _math { return _math{} }, "path": func() _path { return _path{} }, "partial": s.templates.ExecutePartial, "reverse": reverse, @@ -26,6 +28,283 @@ func (s *Site) funcs() map[string]interface{} { } } +type _math struct{} + +func (_math) Add(a, b interface{}) interface{} { + switch a := get64(a).(type) { + case int64: + switch b := get64(b).(type) { + case int64: + return a + b + case float64: + return float64(a) + b + } + case float64: + switch b := get64(b).(type) { + case int64: + return a + float64(b) + case float64: + return a + b + + } + } + panic("invalid input") +} + +func (_math) Sub(a, b interface{}) interface{} { + switch a := get64(a).(type) { + case int64: + switch b := get64(b).(type) { + case int64: + return a - b + case float64: + return float64(a) - b + } + case float64: + switch b := get64(b).(type) { + case int64: + return a - float64(b) + case float64: + return a - b + + } + } + panic("invalid input") +} + +func (_math) Mul(a, b interface{}) interface{} { + switch a := get64(a).(type) { + case int64: + switch b := get64(b).(type) { + case int64: + return a * b + case float64: + return float64(a) * b + } + case float64: + switch b := get64(b).(type) { + case int64: + return a * float64(b) + case float64: + return a * b + + } + } + panic("invalid input") +} + +func (_math) Div(a, b interface{}) float64 { + switch a := get64(a).(type) { + case int64: + switch b := get64(b).(type) { + case int64: + return float64(a) / float64(b) + case float64: + return float64(a) / b + } + case float64: + switch b := get64(b).(type) { + case int64: + return a / float64(b) + case float64: + return a / b + + } + } + panic("invalid input") +} + +func (_math) Mod(a, b interface{}) int64 { + switch a := get64(a).(type) { + case int64: + switch b := get64(b).(type) { + case int64: + return a % b + case float64: + return int64(math.Mod(float64(a), b)) + } + case float64: + switch b := get64(b).(type) { + case int64: + return int64(math.Mod(a, float64(b))) + case float64: + return int64(math.Mod(a, b)) + + } + } + panic("invalid input") +} + +func (_math) Ceil(a interface{}) int64 { + switch a := get64(a).(type) { + case int64: + return a + case float64: + return int64(math.Ceil(a)) + } + panic("invalid input") +} + +func (_math) Floor(a interface{}) int64 { + switch a := get64(a).(type) { + case int64: + return a + case float64: + return int64(math.Floor(a)) + } + panic("invalid input") +} + +func (_math) Log(a interface{}) float64 { + switch a := get64(a).(type) { + case int64: + return math.Log(float64(a)) + case float64: + return math.Log(a) + } + panic("invalid input") +} + +func (_math) Max(a, b interface{}) interface{} { + switch a := get64(a).(type) { + case int64: + switch b := get64(b).(type) { + case int64: + if a >= b { + return a + } else { + return b + } + case float64: + if float64(a) >= b { + return float64(a) + } else { + return b + } + } + case float64: + switch b := get64(b).(type) { + case int64: + if a >= float64(b) { + return a + } else { + return float64(b) + } + case float64: + if a >= b { + return a + } else { + return b + } + } + } + panic("invalid input") +} + +func (_math) Min(a, b interface{}) interface{} { + switch a := get64(a).(type) { + case int64: + switch b := get64(b).(type) { + case int64: + if a <= b { + return a + } else { + return b + } + case float64: + if float64(a) <= b { + return float64(a) + } else { + return b + } + } + case float64: + switch b := get64(b).(type) { + case int64: + if a <= float64(b) { + return a + } else { + return float64(b) + } + case float64: + if a <= b { + return a + } else { + return b + } + } + } + panic("invalid input") +} + +func (_math) Pow(a, b interface{}) float64 { + switch a := get64(a).(type) { + case int64: + switch b := get64(b).(type) { + case int64: + return math.Pow(float64(a), float64(b)) + case float64: + return math.Pow(float64(a), b) + } + case float64: + switch b := get64(b).(type) { + case int64: + return math.Pow(a, float64(b)) + case float64: + return math.Pow(a, b) + } + } + panic("invalid input") +} + +func (_math) Round(a interface{}) int64 { + switch a := get64(a).(type) { + case int64: + return a + case float64: + return int64(math.Round(a)) + } + panic("invalid input") +} + +func (_math) Sqrt(a interface{}) float64 { + switch a := get64(a).(type) { + case int64: + return math.Sqrt(float64(a)) + case float64: + return math.Sqrt(a) + } + panic("invalid input") +} + +func get64(x interface{}) interface{} { + switch x := x.(type) { + case uint8: + return int64(x) + case int8: + return int64(x) + case uint16: + return int64(x) + case int16: + return int64(x) + case uint32: + return int64(x) + case int32: + return int64(x) + case uint64: + return int64(x) + case int64: + return int64(x) + case int: + return int64(x) + case float32: + return float64(x) + case float64: + return float64(x) + } + panic("invalid input") +} + type _path struct{} func (_path) Base(s string) string { return path.Base(s) } -- 2.36.1
--- docs/kiln.1.scd | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/docs/kiln.1.scd b/docs/kiln.1.scd index e995581..0908456 100644 --- a/docs/kiln.1.scd +++ b/docs/kiln.1.scd @@ -621,6 +621,48 @@ All templates have the following functions available to them: *lt* _arg1_, _arg2_ Returns the boolean truth of _arg1_ < _arg2_. +*math.Add* _arg1_, _arg2_ + Returns _arg1_ + _arg2_ as an integer if both arguments are + integers, otherwise as a float. + +*math.Sub* _arg1_, _arg2_ + Returns _arg1_ - _arg2_ as an integer if both arguments are + integers, otherwise as a float. + +*math.Mul* _arg1_, _arg2_ + Returns _arg1_ \* _arg2_ as an integer if both arguments are + integers, otherwise as a float. + +*math.Div* _arg1_, _arg2_ + Returns _arg1_ / _arg2_ as a float. + +*math.Mod* _arg1_, _arg2_ + Returns _arg1_ % _arg2_ as an integer. + +*math.Ceil* _arg_ + Returns the greatest integer value greater than or equal to _arg_. + +*math.Floor* _arg_ + Returns the greatest integer value less than or equal to _arg_. + +*math.Log* _arg_ + Returns the natural logarithm of _arg_ as a float. + +*math.Max* _arg1_, _arg2_ + Returns the greater of _arg1_ and _arg2_ as an integer if both arguments are integers, otherwise as a float. + +*math.Min* _arg1_, _arg2_ + Returns the lesser of _arg1_ and _arg2_ as an integer if both arguments are integers, otherwise as a float. + +*math.Pow* _arg1_, _arg2_ + Returns _arg1_ ^ _arg2_ as a float. + +*math.Round* _arg_ + Returns the nearest integer to _arg_, rounding half away from zero. + +*math.Sqrt* _arg_ + Returns square root of _arg_ as a float. + *ne* _arg1_, _arg2_ Returns the boolean truth of _arg1_ != _arg2_. -- 2.36.1
Pushed with minor edits. Thanks! If you have some time, it might be nice to add some tests for these new math functions in a new file funcs_test.go. To git@git.sr.ht:~adnano/kiln 4f73b34..4e6a81e master -> master