shithub: hugo

Download patch

ref: dfa34afd860208f5688b1e377dce9fccc2825cf9
parent: 2e92f368907c51cfbb2d56c4519604543e2920f5
author: digitalcraftsman <[email protected]>
date: Sun Sep 20 14:15:45 EDT 2015

Add template funcs countwords and countrunes

--- a/docs/content/templates/functions.md
+++ b/docs/content/templates/functions.md
@@ -525,6 +525,26 @@
 e.g. `{{upper "BatMan"}}` → "BATMAN"
 
 
+### countwords
+
+`countwords` tries to convert the passed content to a string and counts each word
+in it. The template functions works similar to [.WordCount]({{< relref "templates/variables.md#page-variables" >}}).
+
+```html
+{{ "Hugo is a static site generator." | countwords }}
+<!-- outputs a content length of 6 words.  -->
+```
+
+
+### countrunes
+
+Alternatively to counting all words , `countrunes` determines the number  of runes in the content and excludes any whitespace. This can become useful if you have to deal with
+CJK-like languages.
+
+```html
+{{ "Hello, 世界" | countrunes }}
+<!-- outputs a content length of 8 runes. -->
+```
 
 
 ## URLs
--- a/tpl/template_funcs.go
+++ b/tpl/template_funcs.go
@@ -26,6 +26,7 @@
 	"strconv"
 	"strings"
 	"time"
+	"unicode/utf8"
 
 	"bitbucket.org/pkg/inflect"
 
@@ -1385,6 +1386,43 @@
 	return base64.StdEncoding.EncodeToString([]byte(conv)), nil
 }
 
+func CountWords(content interface{}) (int, error) {
+	conv, err := cast.ToStringE(content)
+
+	if err != nil {
+		return 0, errors.New("Failed to convert content to string: " + err.Error())
+	}
+
+	counter := 0
+	for _, word := range strings.Fields(helpers.StripHTML(conv)) {
+		runeCount := utf8.RuneCountInString(word)
+		if len(word) == runeCount {
+			counter++
+		} else {
+			counter += runeCount
+		}
+	}
+
+	return counter, nil
+}
+
+func CountRunes(content interface{}) (int, error) {
+	conv, err := cast.ToStringE(content)
+
+	if err != nil {
+		return 0, errors.New("Failed to convert content to string: " + err.Error())
+	}
+
+	counter := 0
+	for _, r := range helpers.StripHTML(conv) {
+		if !helpers.IsWhitespace(r) {
+			counter++
+		}
+	}
+
+	return counter, nil
+}
+
 func init() {
 	funcMap = template.FuncMap{
 		"urlize":       helpers.URLize,
@@ -1444,6 +1482,8 @@
 		"getenv":       func(varName string) string { return os.Getenv(varName) },
 		"base64Decode": Base64Decode,
 		"base64Encode": Base64Encode,
+		"countwords":   CountWords,
+		"countrunes":   CountRunes,
 		"pluralize": func(in interface{}) (string, error) {
 			word, err := cast.ToStringE(in)
 			if err != nil {