Skip to content
Permalink
 
 
Cannot retrieve contributors at this time
// This code is under BSD license. See license-bsd.txt
package main
import (
"path/filepath"
"strings"
"github.com/kjk/u"
)
var (
must = u.Must
panicIf = u.PanicIf
)
func logIfError(err error) {
if err != nil {
logf("%s\n", err)
}
}
// whitelisted characters valid in url
func validateRune(c rune) byte {
if c >= 'a' && c <= 'z' {
return byte(c)
}
if c >= '0' && c <= '9' {
return byte(c)
}
if c == '-' || c == '_' || c == '.' {
return byte(c)
}
if c == ' ' {
return '-'
}
return 0
}
func charCanRepeat(c byte) bool {
if c >= 'a' && c <= 'z' {
return true
}
if c >= '0' && c <= '9' {
return true
}
return false
}
// urlify generates safe url from tile by removing hazardous characters
func urlify(title string) string {
s := strings.TrimSpace(title)
s = strings.ToLower(s)
var res []byte
for _, r := range s {
c := validateRune(r)
if c == 0 {
continue
}
// eliminute duplicate consequitive characters
var prev byte
if len(res) > 0 {
prev = res[len(res)-1]
}
if c == prev && !charCanRepeat(c) {
continue
}
res = append(res, c)
}
s = string(res)
if len(s) > 128 {
s = s[:128]
}
return s
}
func trimEmptyLines(a []string) []string {
var res []string
// remove empty lines from beginning and duplicated empty lines
prevWasEmpty := true
for _, s := range a {
currIsEmpty := (len(s) == 0)
if currIsEmpty && prevWasEmpty {
continue
}
res = append(res, s)
prevWasEmpty = currIsEmpty
}
// remove empty lines from end
for len(res) > 0 {
lastIdx := len(res) - 1
if len(res[lastIdx]) != 0 {
break
}
res = res[:lastIdx]
}
return res
}
func findWordEnd(s string, start int) int {
for i := start; i < len(s); i++ {
c := s[i]
if c == ' ' {
return i + 1
}
}
return -1
}
// remove #tag from start and end
func removeHashTags(s string) (string, []string) {
var tags []string
defer func() {
for i, tag := range tags {
tags[i] = strings.ToLower(tag)
}
}()
// remove hashtags from start
for strings.HasPrefix(s, "#") {
idx := findWordEnd(s, 0)
if idx == -1 {
tags = append(tags, s[1:])
return "", tags
}
tags = append(tags, s[1:idx-1])
s = strings.TrimLeft(s[idx:], " ")
}
// remove hashtags from end
s = strings.TrimRight(s, " ")
for {
idx := strings.LastIndex(s, "#")
if idx == -1 {
return s, tags
}
// tag from the end must not have space after it
if -1 != findWordEnd(s, idx) {
return s, tags
}
// tag from the end must start at the beginning of line
// or be proceded by space
if idx > 0 && s[idx-1] != ' ' {
return s, tags
}
tags = append(tags, s[idx+1:])
s = strings.TrimRight(s[:idx], " ")
}
}
func replaceExt(fileName, newExt string) string {
ext := filepath.Ext(fileName)
if ext == "" {
return fileName
}
n := len(fileName)
s := fileName[:n-len(ext)]
return s + newExt
}
// foo => Foo, BAR => Bar etc.
func capitalize(s string) string {
if len(s) == 0 {
return s
}
s = strings.ToLower(s)
return strings.ToUpper(s[0:1]) + s[1:]
}