summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid E. Wheeler <david@justatheory.com>2018-06-04 13:47:03 -0400
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-06-04 20:47:03 +0300
commit019bd5576be87c9f06b6a928ede1a5e78677f7b3 (patch)
tree2eba3a897b200a127ccd5e2e952551e03a9c5c89
parentc3115292a7f2d2623cb45054a361e997ad9330c9 (diff)
tpl/strings: strings.RuneCount
-rw-r--r--docs/content/en/functions/strings.RuneCount.md28
-rw-r--r--docs/data/docs.json20
-rw-r--r--tpl/strings/init.go5
-rw-r--r--tpl/strings/strings.go9
-rw-r--r--tpl/strings/strings_test.go27
5 files changed, 88 insertions, 1 deletions
diff --git a/docs/content/en/functions/strings.RuneCount.md b/docs/content/en/functions/strings.RuneCount.md
new file mode 100644
index 000000000..63012ab39
--- /dev/null
+++ b/docs/content/en/functions/strings.RuneCount.md
@@ -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 \ No newline at end of file
diff --git a/docs/data/docs.json b/docs/data/docs.json
index 4eddf8eae..3020a21f2 100644
--- a/docs/data/docs.json
+++ b/docs/data/docs.json
@@ -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.",
diff --git a/tpl/strings/init.go b/tpl/strings/init.go
index 883ce76d1..8ff4cf98f 100644
--- a/tpl/strings/init.go
+++ b/tpl/strings/init.go
@@ -41,6 +41,11 @@ func init() {
[][2]string{},
)
+ ns.AddMethodMapping(ctx.RuneCount,
+ nil,
+ [][2]string{},
+ )
+
ns.AddMethodMapping(ctx.CountWords,
[]string{"countwords"},
[][2]string{},
diff --git a/tpl/strings/strings.go b/tpl/strings/strings.go
index d7d8f2d85..1864bb9e0 100644
--- a/tpl/strings/strings.go
+++ b/tpl/strings/strings.go
@@ -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)
diff --git a/tpl/strings/strings_test.go b/tpl/strings/strings_test.go
index 69863c30d..22695ba08 100644
--- a/tpl/strings/strings_test.go
+++ b/tpl/strings/strings_test.go
@@ -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()