tpl/strings: strings.RuneCount

This commit is contained in:
David E. Wheeler 2018-06-04 13:47:03 -04:00 committed by Bjørn Erik Pedersen
parent c3115292a7
commit 019bd5576b
5 changed files with 88 additions and 1 deletions

View file

@ -0,0 +1,28 @@
---
title: strings.RuneCount
description: Determines the number of runes in a string.
godocref:
date: 2018-06-01
publishdate: 2018-06-01
lastmod: 2018-06-01
categories: [functions]
menu:
docs:
parent: "functions"
keywords: [counting, character count, length, rune length, rune count]
signature: ["strings.RuneCount INPUT"]
workson: []
hugoversion:
relatedfuncs: ["len", "countrunes"]
deprecated: false
aliases: []
---
In contrast with `strings.CountRunes` function, which strips HTML and whitespace before counting runes, `strings.RuneCount` simply counts all the runes in a string. It relies on the Go [`utf8.RuneCountInString`] function.
```
{{ "Hello, 世界" | strings.RuneCount }}
<!-- outputs a content length of 9 runes. -->
```
[`utf8.RuneCount`]: https://golang.org/pkg/unicode/utf8/#RuneCount

View file

@ -3146,7 +3146,25 @@
"Aliases": [
"countrunes"
],
"Examples": []
"Examples": [
[
"{{ \"Hello, 世界\" | countrunes }}",
"8"
]
]
},
"RuneCount": {
"Description": "RuneCount returns the number of runes in s",
"Args": [
"s"
],
"Aliases": [],
"Examples": [
[
"{{ \"Hello, 世界\" | strings.RuneCount }}",
"9"
]
]
},
"CountWords": {
"Description": "CountWords returns the approximate word count in s.",

View file

@ -41,6 +41,11 @@ func init() {
[][2]string{},
)
ns.AddMethodMapping(ctx.RuneCount,
nil,
[][2]string{},
)
ns.AddMethodMapping(ctx.CountWords,
[]string{"countwords"},
[][2]string{},

View file

@ -57,6 +57,15 @@ func (ns *Namespace) CountRunes(s interface{}) (int, error) {
return counter, nil
}
// RuneCount returns the number of runes in s.
func (ns *Namespace) RuneCount(s interface{}) (int, error) {
ss, err := cast.ToStringE(s)
if err != nil {
return 0, fmt.Errorf("Failed to convert content to string: %s", err)
}
return utf8.RuneCountInString(ss), nil
}
// CountWords returns the approximate word count in s.
func (ns *Namespace) CountWords(s interface{}) (int, error) {
ss, err := cast.ToStringE(s)

View file

@ -173,6 +173,33 @@ func TestCountRunes(t *testing.T) {
}
}
func TestRuneCount(t *testing.T) {
t.Parallel()
for i, test := range []struct {
s interface{}
expect interface{}
}{
{"foo bar", 7},
{"旁边", 2},
{`<div class="test">旁边</div>`, 26},
// errors
{tstNoStringer{}, false},
} {
errMsg := fmt.Sprintf("[%d] %v", i, test.s)
result, err := ns.RuneCount(test.s)
if b, ok := test.expect.(bool); ok && !b {
require.Error(t, err, errMsg)
continue
}
require.NoError(t, err, errMsg)
assert.Equal(t, test.expect, result, errMsg)
}
}
func TestCountWords(t *testing.T) {
t.Parallel()