func URLFor(endpoint string, values ...interface{}) string {
	url, ok := App.routes[endpoint]
	if !ok {
		return ""
	}
	if len(url) < 1 {
		return ""
	}
	if len(values)%2 != 0 {
		return ""
	}
	params := make(map[string]string)
	if len(values) > 0 {
		key := ""
		for k, v := range values {
			if k%2 == 0 {
				key = fmt.Sprint(v)
			} else {
				params[key] = fmt.Sprint(v)
			}
		}
	}
	urls := strings.Split(url, "/")
	for _, v := range urls {
		if v == "" {
			continue
		}
		if v[0:1] == ":" {
			if u, ok := params[v]; ok {
				delete(params, v)
				url = strings.Replace(url, v, u, 1)
			}
		}
	}
	return url + toURL(params)
}
URLFor returns url string with another registered controller handler with params.
usage:

URLFor(".index")
print URLFor("index")
router /login
print URLFor("login")
print URLFor("login", "next","/"")
router /profile/:username
print UrlFor("profile", ":username","John Doe")
package gin
import (
	"fmt"
	"html"
	"html/template"
	"net/url"
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"time"
	"github.com/pkg/errors"
)
const (
	formatTime      = "15:04:05"
	formatDate      = "2006-01-02"
	formatDateTime  = "2006-01-02 15:04:05"
	formatDateTimeT = "2006-01-02T15:04:05"
)
func Substr(s string, start, length int) string {
	bt := []rune(s)
	if start < 0 {
		start = 0
	}
	if start > len(bt) {
		start = start % len(bt)
	}
	var end int
	if (start + length) > (len(bt) - 1) {
		end = len(bt)
	} else {
		end = start + length
	}
	return string(bt[start:end])
}
func HTML2str(html string) string {
	re := regexp.MustCompile(`\<[\S\s]+?\>`)
	html = re.ReplaceAllStringFunc(html, strings.ToLower)
	re = regexp.MustCompile(`\<style[\S\s]+?\</style\>`)
	html = re.ReplaceAllString(html, "")
	re = regexp.MustCompile(`\<script[\S\s]+?\</script\>`)
	html = re.ReplaceAllString(html, "")
	re = regexp.MustCompile(`\<[\S\s]+?\>`)
	html = re.ReplaceAllString(html, "\n")
	re = regexp.MustCompile(`\s{2,}`)
	html = re.ReplaceAllString(html, "\n")
	return strings.TrimSpace(html)
}
func DateFormat(t time.Time, layout string) (datestring string) {
	datestring = t.Format(layout)
	return
}
var datePatterns = []string{
	"Y", "2006",  
	"y", "06",  
	"m", "01",  
	"n", "1",  
	"M", "Jan",  
	"F", "January",  
	"d", "02",  
	"j", "2",  
	"D", "Mon",  
	"l", "Monday",  
	"g", "3",  
	"G", "15",  
	"h", "03",  
	"H", "15",  
	"a", "pm",  
	"A", "PM",  
	"i", "04",  
	"s", "05",  
	"T", "MST",
	"P", "-07:00",
	"O", "-0700",
	"r", time.RFC1123Z,
}
func DateParse(dateString, format string) (time.Time, error) {
	replacer := strings.NewReplacer(datePatterns...)
	format = replacer.Replace(format)
	return time.ParseInLocation(format, dateString, time.Local)
}
func Date(t time.Time, format string) string {
	replacer := strings.NewReplacer(datePatterns...)
	format = replacer.Replace(format)
	return t.Format(format)
}
func Compare(a, b interface{}) (equal bool) {
	equal = false
	if strings.TrimSpace(fmt.Sprintf("%v", a)) == strings.TrimSpace(fmt.Sprintf("%v", b)) {
		equal = true
	}
	return
}
func CompareNot(a, b interface{}) (equal bool) {
	return !Compare(a, b)
}
func NotNil(a interface{}) (isNil bool) {
	return CompareNot(a, nil)
}
func Str2html(raw string) template.HTML {
	return template.HTML(raw)
}
func Htmlquote(text string) string {
	text = html.EscapeString(text)
	text = strings.NewReplacer(
		`“`, "&ldquo;",
		`”`, "&rdquo;",
		` `, "&nbsp;",
	).Replace(text)
	return strings.TrimSpace(text)
}
func Htmlunquote(text string) string {
	text = html.UnescapeString(text)
	return strings.TrimSpace(text)
}