Exemple #1
0
func Delimit(seq, delimiter interface{}, last ...interface{}) (template.HTML, error) {
	d, err := cast.ToStringE(delimiter)
	if err != nil {
		return "", err
	}

	var dLast *string
	for _, l := range last {
		dStr, err := cast.ToStringE(l)
		if err != nil {
			dLast = nil
		}
		dLast = &dStr
		break
	}

	seqv := reflect.ValueOf(seq)
	seqv, isNil := indirect(seqv)
	if isNil {
		return "", errors.New("can't iterate over a nil value")
	}

	var str string
	switch seqv.Kind() {
	case reflect.Map:
		sortSeq, err := Sort(seq)
		if err != nil {
			return "", err
		}
		seqv = reflect.ValueOf(sortSeq)
		fallthrough
	case reflect.Array, reflect.Slice, reflect.String:
		for i := 0; i < seqv.Len(); i++ {
			val := seqv.Index(i).Interface()
			valStr, err := cast.ToStringE(val)
			if err != nil {
				continue
			}
			switch {
			case i == seqv.Len()-2 && dLast != nil:
				str += valStr + *dLast
			case i == seqv.Len()-1:
				str += valStr
			default:
				str += valStr + d
			}
		}

	default:
		return "", errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String())
	}

	return template.HTML(str), nil
}
Exemple #2
0
// Replace all occurences of b with c in a
func Replace(a, b, c interface{}) (string, error) {
	aStr, err := cast.ToStringE(a)
	if err != nil {
		return "", err
	}
	bStr, err := cast.ToStringE(b)
	if err != nil {
		return "", err
	}
	cStr, err := cast.ToStringE(c)
	if err != nil {
		return "", err
	}
	return strings.Replace(aStr, bStr, cStr, -1), nil
}
Exemple #3
0
func (self *Options) String(key string) string {
	value, err := cast.ToStringE(self.Interface(key))
	if err != nil {
		self.log.Printf("%s for key '%s'", err.Error(), key)
	}
	return value
}
// singularize returns the singular form of a single word.
func singularize(in interface{}) (string, error) {
	word, err := cast.ToStringE(in)
	if err != nil {
		return "", err
	}
	return inflect.Singularize(word), nil
}
// substr extracts parts of a string, beginning at the character at the specified
// position, and returns the specified number of characters.
//
// It normally takes two parameters: start and length.
// It can also take one parameter: start, i.e. length is omitted, in which case
// the substring starting from start until the end of the string will be returned.
//
// To extract characters from the end of the string, use a negative start number.
//
// In addition, borrowing from the extended behavior described at http://php.net/substr,
// if length is given and is negative, then that many characters will be omitted from
// the end of string.
func substr(a interface{}, nums ...interface{}) (string, error) {
	aStr, err := cast.ToStringE(a)
	if err != nil {
		return "", err
	}

	var start, length int

	asRunes := []rune(aStr)

	switch len(nums) {
	case 0:
		return "", errors.New("too less arguments")
	case 1:
		if start, err = cast.ToIntE(nums[0]); err != nil {
			return "", errors.New("start argument must be integer")
		}
		length = len(asRunes)
	case 2:
		if start, err = cast.ToIntE(nums[0]); err != nil {
			return "", errors.New("start argument must be integer")
		}
		if length, err = cast.ToIntE(nums[1]); err != nil {
			return "", errors.New("length argument must be integer")
		}
	default:
		return "", errors.New("too many arguments")
	}

	if start < -len(asRunes) {
		start = 0
	}
	if start > len(asRunes) {
		return "", fmt.Errorf("start position out of bounds for %d-byte string", len(aStr))
	}

	var s, e int
	if start >= 0 && length >= 0 {
		s = start
		e = start + length
	} else if start < 0 && length >= 0 {
		s = len(asRunes) + start - length + 1
		e = len(asRunes) + start + 1
	} else if start >= 0 && length < 0 {
		s = start
		e = len(asRunes) + length
	} else {
		s = len(asRunes) + start
		e = len(asRunes) + length
	}

	if s > e {
		return "", fmt.Errorf("calculated start position greater than end position: %d > %d", s, e)
	}
	if e > len(asRunes) {
		e = len(asRunes)
	}

	return string(asRunes[s:e]), nil
}
Exemple #6
0
// Param is a convenience method to do lookups in Site's Params map.
//
// This method is also implemented on Page.
func (n *Node) Param(key interface{}) (interface{}, error) {
	keyStr, err := cast.ToStringE(key)
	if err != nil {
		return nil, err
	}
	return n.Site.Params[keyStr], err
}
Exemple #7
0
// Trim leading/trailing characters defined by b from a
func Trim(a interface{}, b string) (string, error) {
	aStr, err := cast.ToStringE(a)
	if err != nil {
		return "", err
	}
	return strings.Trim(aStr, b), nil
}
Exemple #8
0
func htmlUnescape(in interface{}) (string, error) {
	conv, err := cast.ToStringE(in)
	if err != nil {
		return "", err
	}
	return html.UnescapeString(conv), nil
}
Exemple #9
0
// Slicing in Slicestr is done by specifying a half-open range with
// two indices, start and end. 1 and 4 creates a slice including elements 1 through 3.
// The end index can be omitted, it defaults to the string's length.
func Slicestr(a interface{}, startEnd ...int) (string, error) {
	aStr, err := cast.ToStringE(a)
	if err != nil {
		return "", err
	}

	if len(startEnd) > 2 {
		return "", errors.New("too many arguments")
	}

	asRunes := []rune(aStr)

	if len(startEnd) > 0 && (startEnd[0] < 0 || startEnd[0] >= len(asRunes)) {
		return "", errors.New("slice bounds out of range")
	}

	if len(startEnd) == 2 {
		if startEnd[1] < 0 || startEnd[1] > len(asRunes) {
			return "", errors.New("slice bounds out of range")
		}
		return string(asRunes[startEnd[0]:startEnd[1]]), nil
	} else if len(startEnd) == 1 {
		return string(asRunes[startEnd[0]:]), nil
	} else {
		return string(asRunes[:]), nil
	}

}
Exemple #10
0
func Split(a interface{}, delimiter string) ([]string, error) {
	aStr, err := cast.ToStringE(a)
	if err != nil {
		return []string{}, err
	}
	return strings.Split(aStr, delimiter), nil
}
Exemple #11
0
func (c *Configr) String(key string) (string, error) {
	val, err := c.Get(key)
	if err != nil {
		return "", err
	}
	return cast.ToStringE(val)
}
Exemple #12
0
// emojify "emojifies" the given string.
//
// See http://www.emoji-cheat-sheet.com/
func emojify(in interface{}) (template.HTML, error) {
	str, err := cast.ToStringE(in)

	if err != nil {
		return "", err
	}
	return template.HTML(helpers.Emojify([]byte(str))), nil
}
Exemple #13
0
func Chomp(text interface{}) (string, error) {
	s, err := cast.ToStringE(text)
	if err != nil {
		return "", err
	}

	return strings.TrimRight(s, "\r\n"), nil
}
// chomp removes trailing newline characters from a string.
func chomp(text interface{}) (template.HTML, error) {
	s, err := cast.ToStringE(text)
	if err != nil {
		return "", err
	}

	return template.HTML(strings.TrimRight(s, "\r\n")), nil
}
// sha1 hashes the given input and returns its SHA1 checksum
func sha1(in interface{}) (string, error) {
	conv, err := cast.ToStringE(in)
	if err != nil {
		return "", err
	}

	hash := _sha1.Sum([]byte(conv))
	return hex.EncodeToString(hash[:]), nil
}
// highlight returns an HTML string with syntax highlighting applied.
func highlight(in interface{}, lang, opts string) (template.HTML, error) {
	str, err := cast.ToStringE(in)

	if err != nil {
		return "", err
	}

	return template.HTML(helpers.Highlight(html.UnescapeString(str), lang, opts)), nil
}
// plainify strips any HTML and returns the plain text version.
func plainify(in interface{}) (string, error) {
	s, err := cast.ToStringE(in)

	if err != nil {
		return "", err
	}

	return helpers.StripHTML(s), nil
}
// base64Encode returns the base64 encoding of the given content.
func base64Encode(content interface{}) (string, error) {
	conv, err := cast.ToStringE(content)

	if err != nil {
		return "", err
	}

	return base64.StdEncoding.EncodeToString([]byte(conv)), nil
}
Exemple #19
0
// Param is a convenience method to do lookups in Page's and Site's Params map,
// in that order.
//
// This method is also implemented on Node.
func (p *Page) Param(key interface{}) (interface{}, error) {
	keyStr, err := cast.ToStringE(key)
	if err != nil {
		return nil, err
	}
	if val, ok := p.Params[keyStr]; ok {
		return val, nil
	}
	return p.Site.Params[keyStr], nil
}
Exemple #20
0
func (p *Page) Menus() PageMenus {
	p.pageMenusInit.Do(func() {
		p.pageMenus = PageMenus{}

		if ms, ok := p.Params["menu"]; ok {
			link, _ := p.RelPermalink()

			me := MenuEntry{Name: p.LinkTitle(), Weight: p.Weight, URL: link}

			// Could be the name of the menu to attach it to
			mname, err := cast.ToStringE(ms)

			if err == nil {
				me.Menu = mname
				p.pageMenus[mname] = &me
				return
			}

			// Could be a slice of strings
			mnames, err := cast.ToStringSliceE(ms)

			if err == nil {
				for _, mname := range mnames {
					me.Menu = mname
					p.pageMenus[mname] = &me
				}
				return
			}

			// Could be a structured menu entry
			menus, err := cast.ToStringMapE(ms)

			if err != nil {
				jww.ERROR.Printf("unable to process menus for %q\n", p.Title)
			}

			for name, menu := range menus {
				menuEntry := MenuEntry{Name: p.LinkTitle(), URL: link, Weight: p.Weight, Menu: name}
				if menu != nil {
					jww.DEBUG.Printf("found menu: %q, in %q\n", name, p.Title)
					ime, err := cast.ToStringMapE(menu)
					if err != nil {
						jww.ERROR.Printf("unable to process menus for %q: %s", p.Title, err)
					}

					menuEntry.marshallMap(ime)
				}
				p.pageMenus[name] = &menuEntry

			}
		}
	})

	return p.pageMenus
}
// base64Decode returns the base64 decoding of the given content.
func base64Decode(content interface{}) (string, error) {
	conv, err := cast.ToStringE(content)

	if err != nil {
		return "", err
	}

	dec, err := base64.StdEncoding.DecodeString(conv)

	return string(dec), err
}
Exemple #22
0
// GetString takes the name of an argument and returns a string and an error.
func (args Args) GetString(name string) (string, error) {
	v, ok := args[name]
	if !ok {
		return "<invalid argument>", ErrNoArg
	}

	str, err := cast.ToStringE(v)
	if err != nil {
		return "<failed to cast>", err
	}
	return str, nil
}
// humanize returns the humanized form of a single word.
// Example:  "my-first-post" -> "My first post"
func humanize(in interface{}) (string, error) {
	word, err := cast.ToStringE(in)
	if err != nil {
		return "", err
	}

	if word == "" {
		return "", nil
	}

	return inflect.Humanize(word), nil
}
Exemple #24
0
func (page *Page) Menus() PageMenus {
	ret := PageMenus{}

	if ms, ok := page.Params["menu"]; ok {
		link, _ := page.Permalink()

		me := MenuEntry{Name: page.LinkTitle(), Weight: page.Weight, Url: link}

		// Could be the name of the menu to attach it to
		mname, err := cast.ToStringE(ms)

		if err == nil {
			me.Menu = mname
			ret[mname] = &me
			return ret
		}

		// Could be an slice of strings
		mnames, err := cast.ToStringSliceE(ms)

		if err == nil {
			for _, mname := range mnames {
				me.Menu = mname
				ret[mname] = &me
				return ret
			}
		}

		// Could be a structured menu entry
		menus, err := cast.ToStringMapE(ms)

		if err != nil {
			jww.ERROR.Printf("unable to process menus for %q\n", page.Title)
		}

		for name, menu := range menus {
			menuEntry := MenuEntry{Name: page.LinkTitle(), Url: link, Weight: page.Weight, Menu: name}
			jww.DEBUG.Printf("found menu: %q, in %q\n", name, page.Title)

			ime, err := cast.ToStringMapE(menu)
			if err != nil {
				jww.ERROR.Printf("unable to process menus for %q\n", page.Title)
			}

			menuEntry.MarshallMap(ime)
			ret[name] = &menuEntry
		}
		return ret
	}

	return nil
}
// replaceRE exposes a regular expression replacement function to the templates.
func replaceRE(pattern, repl, src interface{}) (_ string, err error) {
	patternStr, err := cast.ToStringE(pattern)
	if err != nil {
		return
	}

	replStr, err := cast.ToStringE(repl)
	if err != nil {
		return
	}

	srcStr, err := cast.ToStringE(src)
	if err != nil {
		return
	}

	re, err := reCache.Get(patternStr)
	if err != nil {
		return "", err
	}
	return re.ReplaceAllString(srcStr, replStr), nil
}
Exemple #26
0
// Substr extracts parts of a string, beginning at the character at the specified
// position, and returns the specified number of characters.
//
// It normally takes two parameters: start and length.
// It can also take one parameter: start, i.e. length is omitted, in which case
// the substring starting from start until the end of the string will be returned.
//
// To extract characters from the end of the string, use a negative start number.
//
// In addition, borrowing from the extended behavior described at http://php.net/substr,
// if length is given and is negative, then that many characters will be omitted from
// the end of string.
func Substr(a interface{}, nums ...int) (string, error) {
	aStr, err := cast.ToStringE(a)
	if err != nil {
		return "", err
	}

	var start, length int
	switch len(nums) {
	case 1:
		start = nums[0]
		length = len(aStr)
	case 2:
		start = nums[0]
		length = nums[1]
	default:
		return "", errors.New("too many arguments")
	}

	if start < -len(aStr) {
		start = 0
	}
	if start > len(aStr) {
		return "", errors.New(fmt.Sprintf("start position out of bounds for %d-byte string", len(aStr)))
	}

	var s, e int
	if start >= 0 && length >= 0 {
		s = start
		e = start + length
	} else if start < 0 && length >= 0 {
		s = len(aStr) + start - length + 1
		e = len(aStr) + start + 1
	} else if start >= 0 && length < 0 {
		s = start
		e = len(aStr) + length
	} else {
		s = len(aStr) + start
		e = len(aStr) + length
	}

	if s > e {
		return "", errors.New(fmt.Sprintf("calculated start position greater than end position: %d > %d", s, e))
	}
	if e > len(aStr) {
		e = len(aStr)
	}

	return aStr[s:e], nil

}
Exemple #27
0
func Sort(seq interface{}, args ...interface{}) ([]interface{}, error) {
	seqv := reflect.ValueOf(seq)
	seqv, isNil := indirect(seqv)
	if isNil {
		return nil, errors.New("can't iterate over a nil value")
	}

	// Create a list of pairs that will be used to do the sort
	p := pairList{SortAsc: true}
	p.Pairs = make([]pair, seqv.Len())

	for i, l := range args {
		dStr, err := cast.ToStringE(l)
		switch {
		case i == 0 && err != nil:
			p.SortByField = ""
		case i == 0 && err == nil:
			p.SortByField = dStr
		case i == 1 && err == nil && dStr == "desc":
			p.SortAsc = false
		case i == 1:
			p.SortAsc = true
		}
	}

	var sorted []interface{}
	switch seqv.Kind() {
	case reflect.Array, reflect.Slice:
		for i := 0; i < seqv.Len(); i++ {
			p.Pairs[i].Key = reflect.ValueOf(i)
			p.Pairs[i].Value = seqv.Index(i)
		}
		if p.SortByField == "" {
			p.SortByField = "value"
		}

	case reflect.Map:
		keys := seqv.MapKeys()
		for i := 0; i < seqv.Len(); i++ {
			p.Pairs[i].Key = keys[i]
			p.Pairs[i].Value = seqv.MapIndex(keys[i])
		}

	default:
		return nil, errors.New("can't sort " + reflect.ValueOf(seq).Type().String())
	}
	sorted = p.sort()
	return sorted, nil
}
// countRunes returns the approximate rune count of the given content.
func countRunes(content interface{}) (int, error) {
	conv, err := cast.ToStringE(content)

	if err != nil {
		return 0, fmt.Errorf("Failed to convert content to string: %s", err.Error())
	}

	counter := 0
	for _, r := range helpers.StripHTML(conv) {
		if !helpers.IsWhitespace(r) {
			counter++
		}
	}

	return counter, nil
}
Exemple #29
0
// humanize returns the humanized form of a single parameter.
// If the parameter is either an integer or a string containing an integer
// value, the behavior is to add the appropriate ordinal.
// Example:  "my-first-post" -> "My first post"
// Example:  "103" -> "103rd"
// Example:  52 -> "52nd"
func humanize(in interface{}) (string, error) {
	word, err := cast.ToStringE(in)
	if err != nil {
		return "", err
	}

	if word == "" {
		return "", nil
	}

	_, ok := in.(int)           // original param was literal int value
	_, err = strconv.Atoi(word) // original param was string containing an int value
	if ok == true || err == nil {
		return inflect.Ordinalize(word), nil
	}
	return inflect.Humanize(word), nil
}
// slicestr slices a string by specifying a half-open range with
// two indices, start and end. 1 and 4 creates a slice including elements 1 through 3.
// The end index can be omitted, it defaults to the string's length.
func slicestr(a interface{}, startEnd ...interface{}) (string, error) {
	aStr, err := cast.ToStringE(a)
	if err != nil {
		return "", err
	}

	var argStart, argEnd int

	argNum := len(startEnd)

	if argNum > 0 {
		if argStart, err = cast.ToIntE(startEnd[0]); err != nil {
			return "", errors.New("start argument must be integer")
		}
	}
	if argNum > 1 {
		if argEnd, err = cast.ToIntE(startEnd[1]); err != nil {
			return "", errors.New("end argument must be integer")
		}
	}

	if argNum > 2 {
		return "", errors.New("too many arguments")
	}

	asRunes := []rune(aStr)

	if argNum > 0 && (argStart < 0 || argStart >= len(asRunes)) {
		return "", errors.New("slice bounds out of range")
	}

	if argNum == 2 {
		if argEnd < 0 || argEnd > len(asRunes) {
			return "", errors.New("slice bounds out of range")
		}
		return string(asRunes[argStart:argEnd]), nil
	} else if argNum == 1 {
		return string(asRunes[argStart:]), nil
	} else {
		return string(asRunes[:]), nil
	}

}