Example #1
1
File: gas.go Project: moshee/gas
// ToSnake is a utility function that converts from camelCase to snake_case.
func ToSnake(in string) string {
	if len(in) == 0 {
		return ""
	}

	out := make([]rune, 0, len(in))
	foundUpper := false
	r := []rune(in)

	for i := 0; i < len(r); i++ {
		ch := r[i]
		if unicode.IsUpper(ch) {
			if i > 0 && i < len(in)-1 && !unicode.IsUpper(r[i+1]) {
				out = append(out, '_', unicode.ToLower(ch), r[i+1])
				i++
				continue
				foundUpper = false
			}
			if i > 0 && !foundUpper {
				out = append(out, '_')
			}
			out = append(out, unicode.ToLower(ch))
			foundUpper = true
		} else {
			foundUpper = false
			out = append(out, ch)
		}
	}
	return string(out)
}
Example #2
1
// Is the item exported from the package?
func (n *Named) Exported() bool {
	if n.Imported() {
		return false
	}
	r, _ := utf8.DecodeRuneInString(n.Name)
	return unicode.IsUpper(r)
}
Example #3
0
// ToLatin returns a string transliterated using provided mapping table.
// Runes that cannot be transliterated inserted as-is.
func ToLatin(s string, table map[int]string) string {
	runes := []int(s)
	out := make([]int, 0, len(s))
	for i, rune := range runes {
		if tr, ok := table[unicode.ToLower(rune)]; ok {
			if tr == "" {
				continue
			}
			if unicode.IsUpper(rune) {
				// Correctly translate case of successive characters:
				// ЩИ -> SCHI
				// Щи -> Schi
				if i+1 < len(runes) && !unicode.IsUpper(runes[i+1]) {
					t := []int(tr)
					t[0] = unicode.ToUpper(t[0])
					out = append(out, t...)
					continue
				}
				out = append(out, []int(strings.ToUpper(tr))...)
				continue
			}
			out = append(out, []int(tr)...)
		} else {
			out = append(out, rune)
		}
	}
	return string(out)
}
Example #4
0
func ConvertToUnderscore(camel string) (string, error) {
	var prevRune rune
	var underscore []rune
	for index, runeChar := range camel {
		if index == 0 {
			if !unicode.IsLetter(runeChar) {
				return "", fmt.Errorf("Table and column names can't start with a character other than a letter.")
			}
			underscore = append(underscore, unicode.ToLower(runeChar))
			prevRune = runeChar
		} else {
			if runeChar == '_' || unicode.IsLetter(runeChar) || unicode.IsDigit(runeChar) {
				//Look for Upper case letters, append _ and make character lower case
				if unicode.IsUpper(runeChar) {
					if !unicode.IsUpper(prevRune) {
						underscore = append(underscore, '_')
					}
					underscore = append(underscore, unicode.ToLower(runeChar))
				} else {
					underscore = append(underscore, runeChar)
				}
			} else {
				return "", fmt.Errorf("Table and column names can't contain non-alphanumeric characters.")
			}
		}
		prevRune = runeChar
	}
	return string(underscore), nil
}
Example #5
0
File: mapper.go Project: jonasi/env
// UnderscoreMapper converts CamelCase strings to their camel_case
// counterpart
func UnderscoreMapper(str string) string {
	var (
		parts = []string{}
		cur   = []rune{}
		last2 = [2]rune{}
	)

	for _, c := range str {
		if unicode.IsUpper(c) {
			if last2[1] != 0 && unicode.IsLower(last2[1]) {
				parts = append(parts, string(cur))
				cur = nil
			}

			cur = append(cur, unicode.ToLower(c))
		} else {
			if last2[0] != 0 && last2[1] != 0 && unicode.IsUpper(last2[0]) && unicode.IsUpper(last2[1]) {
				parts = append(parts, string(cur[:len(cur)-1]))
				cur = []rune{cur[len(cur)-1]}
			}

			cur = append(cur, c)
		}

		last2[0] = last2[1]
		last2[1] = c
	}

	if len(cur) > 0 {
		parts = append(parts, string(cur))
	}

	return strings.Join(parts, "_")
}
Example #6
0
func getFuncs(prog *ssa.Program, pkg *ssa.Package) []*ssa.Function {
	funcs := make([]*ssa.Function, 0, len(pkg.Members))
	for _, mem := range pkg.Members {
		fn, ok := mem.(*ssa.Function)
		if ok {
			if iu := unicode.IsUpper(rune(fn.Name()[0])); iu || *nonExp {
				funcs = append(funcs, fn)
			}
		}
		typ, ok := mem.(*ssa.Type)
		if ok {
			mset := prog.MethodSets.MethodSet(typ.Type())
			for i, n := 0, mset.Len(); i < n; i++ {
				if mf := prog.MethodValue(mset.At(i)); mf != nil {
					if mfn := mf.Name(); len(mfn) > 0 {
						if iu := unicode.IsUpper(rune(mfn[0])); iu || *nonExp {
							funcs = append(funcs, mf)
							//fmt.Printf("DEBUG method %v %v\n", mfn, mf)
						}
					}
				}
			}
		}
	}
	return funcs
}
Example #7
0
func Rename(filename string, line int, column int, newName string) (ok bool, err *errors.GoRefactorError) {

	if ok, err = CheckRenameParameters(filename, line, column, newName); !ok {
		return
	}

	programTree := parseProgram(filename)

	var sym st.Symbol
	if sym, err = programTree.FindSymbolByPosition(filename, line, column); err == nil {

		if _, ok := sym.(*st.PointerTypeSymbol); ok {
			panic("find by position returned pointer type!!!")
		}
		if st.IsPredeclaredIdentifier(sym.Name()) {
			return false, errors.UnrenamableIdentifierError(sym.Name(), " It's a basic language symbol")
		}
		if sym.PackageFrom().IsGoPackage {
			return false, errors.UnrenamableIdentifierError(sym.Name(), " It's a symbol,imported from go library")
		}
		if unicode.IsUpper(int(sym.Name()[0])) && !unicode.IsUpper(int(newName[0])) ||
			unicode.IsLower(int(sym.Name()[0])) && !unicode.IsLower(int(newName[0])) {
			return false, &errors.GoRefactorError{ErrorType: "Can't rename identifier", Message: "can't change access modifier. Changing first letter's case can cause errors."}
		}
		if _, ok := sym.Scope().LookUp(newName, filename); ok {
			return false, errors.IdentifierAlreadyExistsError(newName)
		}

		if meth, ok := sym.(*st.FunctionSymbol); ok {
			if meth.IsInterfaceMethod {
				return false, errors.UnrenamableIdentifierError(sym.Name(), " It's an interface method")
			}
		}
		if ps, ok := sym.(*st.PackageSymbol); ok {
			pack, file := programTree.FindPackageAndFileByFilename(filename)
			impDecl := findImportDecl(pack, file, ps)
			if impDecl == nil {
				panic("couldn't find import decl")
			}
			if impDecl.Name == nil || impDecl.Name.Name == "" {
				impDecl.Name = ast.NewIdent(newName)
			}
		}
		fnames, fsets, files, err := renameSymbol(sym, newName, programTree)
		if err == nil {
			for i, f := range fnames {
				programTree.SaveFileExplicit(f, fsets[i], files[i])
			}
		}
		return err == nil, err
	} else {
		return false, err
	}
	panic("unreachable code")
}
Example #8
0
func Snake(name string) (r string) {
	// first two letters are upcase like URL, MD5, HTTPRequest etc, keep it as it is.
	if len(name) >= 2 {
		if unicode.IsUpper([]rune(name)[0]) && (unicode.IsUpper([]rune(name)[1]) || unicode.IsNumber([]rune(name)[1])) {
			return name
		}
	}

	r = strings.ToLower(name[:1]) + name[1:]
	return
}
Example #9
0
func isUpperFold(rune int) bool {
	if unicode.IsUpper(rune) {
		return true
	}
	c := unicode.SimpleFold(rune)
	for c != rune {
		if unicode.IsUpper(c) {
			return true
		}
		c = unicode.SimpleFold(c)
	}
	return false
}
Example #10
0
func lintCapAndPunct(s string) (isCap, isPunct bool) {
	first, firstN := utf8.DecodeRuneInString(s)
	last, _ := utf8.DecodeLastRuneInString(s)
	isPunct = last == '.' || last == ':' || last == '!'
	isCap = unicode.IsUpper(first)
	if isCap && len(s) > firstN {
		// Don't flag strings starting with something that looks like an initialism.
		if second, _ := utf8.DecodeRuneInString(s[firstN:]); unicode.IsUpper(second) {
			isCap = false
		}
	}
	return
}
Example #11
0
// firstSentenceLen returns the length of the first sentence in s.
// The sentence ends after the first period followed by space and
// not preceded by exactly one uppercase letter.
//
func firstSentenceLen(s string) int {
	var ppp, pp, p rune
	for i, q := range s {
		if q == '\n' || q == '\r' || q == '\t' {
			q = ' '
		}
		if q == ' ' && p == '.' && (!unicode.IsUpper(pp) || unicode.IsUpper(ppp)) {
			return i
		}
		ppp, pp, p = pp, p, q
	}
	return len(s)
}
Example #12
0
func CompareMethodsByVisibility(d1 *ast.FuncDecl, d2 *ast.FuncDecl) int {
	n1 := getDeclName(d1)
	n2 := getDeclName(d2)
	b1 := unicode.IsUpper(int(n1[0]))
	b2 := unicode.IsUpper(int(n2[0]))
	switch {
	case b1 && !b2:
		return 1
	case !b1 && b2:
		return -1
	}
	return 0
}
Example #13
0
func extraUpperCaseEntropy(match match.Match) float64 {
	word := match.Token

	allLower := true

	for _, char := range word {
		if unicode.IsUpper(char) {
			allLower = false
			break
		}
	}
	if allLower {
		return float64(0)
	}

	//a capitalized word is the most common capitalization scheme,
	//so it only doubles the search space (uncapitalized + capitalized): 1 extra bit of entropy.
	//allcaps and end-capitalized are common enough too, underestimate as 1 extra bit to be safe.

	for _, regex := range []string{START_UPPER, END_UPPER, ALL_UPPER} {
		matcher := regexp.MustCompile(regex)

		if matcher.MatchString(word) {
			return float64(1)
		}
	}
	//Otherwise calculate the number of ways to capitalize U+L uppercase+lowercase letters with U uppercase letters or
	//less. Or, if there's more uppercase than lower (for e.g. PASSwORD), the number of ways to lowercase U+L letters
	//with L lowercase letters or less.

	countUpper, countLower := float64(0), float64(0)
	for _, char := range word {
		if unicode.IsUpper(char) {
			countUpper++
		} else if unicode.IsLower(char) {
			countLower++
		}
	}
	totalLenght := countLower + countUpper
	var possibililities float64

	for i := float64(0); i <= math.Min(countUpper, countLower); i++ {
		possibililities += float64(zxcvbn_math.NChoseK(totalLenght, i))
	}

	if possibililities < 1 {
		return float64(1)
	}

	return float64(math.Log2(possibililities))
}
Example #14
0
func camelToUnderscore(name string) string {
	rv := ""
	for i, r := range name {
		if unicode.IsUpper(r) && i != 0 {
			rv += "_"
			rv += string(unicode.ToLower(r))
		} else if unicode.IsUpper(r) && i == 0 {
			rv += string(unicode.ToLower(r))
		} else {
			rv += string(r)
		}
	}
	return rv
}
Example #15
0
// camelToSnakeCase converts a string containing one or more camel
// cased words into their snake cased equivalents. For example,
// "CamelCase" results in "camel_case".
func camelToSnakeCase(s string) string {
	result := ""
	boundary := true // Are we on a word boundary?
	for _, r := range s {
		if unicode.IsUpper(r) && !boundary {
			result += "_" + string(unicode.ToLower(r))
		} else if unicode.IsUpper(r) {
			result += string(unicode.ToLower(r))
		} else {
			result += string(r)
		}
		boundary = !(unicode.IsLetter(r) || unicode.IsDigit(r))
	}
	return result
}
Example #16
0
func firstSentence(s string) string {
	i := -1 // index+1 of first period
	j := -1 // index+1 of first period that is followed by white space
	prev := 'A'
	for k, ch := range s {
		k1 := k + 1
		if ch == '.' {
			if i < 0 {
				i = k1 // first period
			}
			if k1 < len(s) && s[k1] <= ' ' {
				if j < 0 {
					j = k1 // first period followed by white space
				}
				if !unicode.IsUpper(prev) {
					j = k1
					break
				}
			}
		}
		prev = ch
	}

	if j < 0 {
		// use the next best period
		j = i
		if j < 0 {
			// no period at all, use the entire string
			j = len(s)
		}
	}

	return s[0:j]
}
Example #17
0
func firstSentence(s string) string {
	i := -1 // index+1 of first terminator (punctuation ending a sentence)
	j := -1 // index+1 of first terminator followed by white space
	prev := 'A'
	for k, ch := range s {
		k1 := k + 1
		if ch == '.' || ch == '!' || ch == '?' {
			if i < 0 {
				i = k1 // first terminator
			}
			if k1 < len(s) && s[k1] <= ' ' {
				if j < 0 {
					j = k1 // first terminator followed by white space
				}
				if !unicode.IsUpper(prev) {
					j = k1
					break
				}
			}
		}
		prev = ch
	}

	if j < 0 {
		// use the next best terminator
		j = i
		if j < 0 {
			// no terminator at all, use the entire string
			j = len(s)
		}
	}

	return s[0:j]
}
func isSecretStrengthOk(pass string) error {
	extraCnt := 0
	digitCnt := 0
	upperCaseCnt := 0
	lowerCaseCnt := 0

	for _, c := range extraCharStr {
		extraCnt += strings.Count(pass, string(c))
	}
	for _, c := range pass {
		if unicode.IsUpper(c) {
			upperCaseCnt++
		} else if unicode.IsLower(c) {
			lowerCaseCnt++
		} else if unicode.IsDigit(c) {
			digitCnt++
		}
	}
	if len(pass) < minSecretLen || extraCnt < minExtraChars || digitCnt < minDigits ||
		upperCaseCnt < minUpperCase || lowerCaseCnt < minLowerCase {
		return fmt.Errorf("The secure storage secret does not pass the secret strength test. In order to be strong, the password must adhere to all of the following:\nContains at least %v characters\nInclude at least: %v digits\nInclude at least %v letters where at least %v must be upper-case and at least %v must be lower-case\nInclude at least %v special characters from the following list:\nSpecial characters: '%v'",
			minSecretLen, minDigits, minUpperCase+minLowerCase, minUpperCase, minLowerCase, minExtraChars, extraCharStr)
	}
	return nil
}
Example #19
0
File: ast.go Project: velour/stop
// Exported returns whether the identifier is exported.
func (n *Identifier) Exported() bool {
	r, sz := utf8.DecodeRuneInString(n.Name)
	if r == utf8.RuneError && sz == 1 {
		return false
	}
	return unicode.IsUpper(r)
}
Example #20
0
// SnakeCase produces the snake_case version of the given CamelCase string.
func SnakeCase(name string) string {
	for u, l := range toLower {
		name = strings.Replace(name, u, l, -1)
	}
	var b bytes.Buffer
	var lastUnderscore bool
	ln := len(name)
	if ln == 0 {
		return ""
	}
	b.WriteRune(unicode.ToLower(rune(name[0])))
	for i := 1; i < ln; i++ {
		r := rune(name[i])
		nextIsLower := false
		if i < ln-1 {
			n := rune(name[i+1])
			nextIsLower = unicode.IsLower(n) && unicode.IsLetter(n)
		}
		if unicode.IsUpper(r) {
			if !lastUnderscore && nextIsLower {
				b.WriteRune('_')
				lastUnderscore = true
			}
			b.WriteRune(unicode.ToLower(r))
		} else {
			b.WriteRune(r)
			lastUnderscore = false
		}
	}
	return b.String()
}
Example #21
0
func exportname(s string) bool {
	if r := s[0]; r < utf8.RuneSelf {
		return 'A' <= r && r <= 'Z'
	}
	r, _ := utf8.DecodeRuneInString(s)
	return unicode.IsUpper(r)
}
Example #22
0
func (h *HeaderFile) addBasicMethods(f *Function, fname string, fnamePrefix string, rt Receiver) bool {
	if len(f.Parameters) == 0 && h.IsEnumOrStruct(f.ReturnType.GoName) {
		rtc := rt
		rtc.Type = f.ReturnType

		fname = TrimCommonFunctionNamePrefix(fname)
		if fname == "" {
			fname = f.ReturnType.GoName
		}

		if strings.HasPrefix(f.CName, "clang_create") || strings.HasPrefix(f.CName, "clang_get") || strings.HasSuffix(f.CName, "_create") {
			fname = "New" + fname
		}

		return h.addMethod(f, fname, fnamePrefix, rtc)
	} else if (fname[0] == 'i' && fname[1] == 's' && unicode.IsUpper(rune(fname[2]))) || (fname[0] == 'h' && fname[1] == 'a' && fname[2] == 's' && unicode.IsUpper(rune(fname[3]))) {
		f.ReturnType.GoName = "bool"

		return h.addMethod(f, fname, fnamePrefix, rt)
	} else if len(f.Parameters) == 1 && h.IsEnumOrStruct(f.Parameters[0].Type.GoName) && strings.HasPrefix(fname, "dispose") && f.ReturnType.GoName == "void" {
		fname = "Dispose"

		return h.addMethod(f, fname, fnamePrefix, rt)
	} else if len(f.Parameters) == 2 && strings.HasPrefix(fname, "equal") && h.IsEnumOrStruct(f.Parameters[0].Type.GoName) && f.Parameters[0].Type == f.Parameters[1].Type {
		fname = "Equal"
		f.Parameters[0].Name = commonReceiverName(f.Parameters[0].Type.GoName)
		f.Parameters[1].Name = f.Parameters[0].Name + "2"

		f.ReturnType.GoName = "bool"

		return h.addMethod(f, fname, fnamePrefix, rt)
	}

	return false
}
Example #23
0
func (p *docPrinter) printExamples(name string) {
	for _, e := range p.examples {
		if !strings.HasPrefix(e.Name, name) {
			continue
		}
		name := e.Name[len(name):]
		if name != "" {
			if i := strings.LastIndex(name, "_"); i != 0 {
				continue
			}
			name = name[1:]
			if r, _ := utf8.DecodeRuneInString(name); unicode.IsUpper(r) {
				continue
			}
			name = strings.Title(name)
		}

		var node interface{}
		if _, ok := e.Code.(*ast.File); ok {
			node = e.Play
		} else {
			node = &printer.CommentedNode{Node: e.Code, Comments: e.Comments}
		}

		var buf bytes.Buffer
		err := (&printer.Config{Tabwidth: 4}).Fprint(&buf, p.fset, node)
		if err != nil {
			continue
		}

		// Additional formatting if this is a function body.
		b := buf.Bytes()
		if i := len(b); i >= 2 && b[0] == '{' && b[i-1] == '}' {
			// Remove surrounding braces.
			b = b[1 : i-1]
			// Unindent
			b = bytes.Replace(b, []byte("\n    "), []byte("\n"), -1)
			// Remove output comment
			if j := exampleOutputRx.FindIndex(b); j != nil {
				b = bytes.TrimSpace(b[:j[0]])
			}
		} else {
			// Drop output, as the output comment will appear in the code
			e.Output = ""
		}

		// Hide examples for now. I tried displaying comments inline and folded
		// and found them both distracting. Consider includling link from doc
		// to examples at the end of the page.
		/*
			p.buf.Write(b)
			p.buf.WriteByte('\n')
			if e.Output != "" {
				p.buf.WriteString(e.Output)
				buf.WriteByte('\n')
			}
			p.buf.WriteByte('\n')
		*/
	}
}
Example #24
0
func test_password(pass string) bool {
	// Windows AD password needs at leat 7 characters password,  and must contain characters from three of the following five categories:
	// uppercase character
	// lowercase character
	// digit character
	// nonalphanumeric characters
	// any Unicode character that is categorized as an alphabetic character but is not uppercase or lowercase
	if len(pass) < 7 {
		return false
	}
	d := 0
	l := 0
	u := 0
	p := 0
	o := 0
	for _, c := range pass {
		if unicode.IsDigit(c) { // check digit character
			d = 1
		} else if unicode.IsLower(c) { // check lowercase character
			l = 1
		} else if unicode.IsUpper(c) { // check uppercase character
			u = 1
		} else if unicode.IsPunct(c) { // check nonalphanumeric character
			p = 1
		} else { // other unicode character
			o = 1
		}
	}
	if d+l+u+p+o < 3 {
		return false
	}
	return true
}
Example #25
0
// Stat calculates statistics for all runes read from r.
func (m *Main) Stat(r io.RuneReader) (Stats, error) {
	var stats Stats

	for {
		// Read next character.
		ch, sz, err := r.ReadRune()
		if err == io.EOF {
			break
		} else if err != nil {
			return stats, err
		}

		// Calculate stats.
		stats.TotalN++
		if unicode.IsControl(ch) {
			stats.ControlN++
		}
		if unicode.IsDigit(ch) {
			stats.DigitN++
		}
		if unicode.IsGraphic(ch) {
			stats.GraphicN++
		}
		if unicode.IsLetter(ch) {
			stats.LetterN++
		}
		if unicode.IsLower(ch) {
			stats.LowerN++
		}
		if unicode.IsMark(ch) {
			stats.MarkN++
		}
		if unicode.IsNumber(ch) {
			stats.NumberN++
		}
		if unicode.IsPrint(ch) {
			stats.PrintN++
		}
		if unicode.IsPunct(ch) {
			stats.PunctN++
		}
		if unicode.IsSpace(ch) {
			stats.SpaceN++
		}
		if unicode.IsSymbol(ch) {
			stats.SymbolN++
		}
		if unicode.IsTitle(ch) {
			stats.TitleN++
		}
		if unicode.IsUpper(ch) {
			stats.UpperN++
		}
		if sz > 1 {
			stats.MultiByteN++
		}
	}

	return stats, nil
}
Example #26
0
// Emit the Global declarations, run inside the Go class declaration output.
func emitGlobals() {
	allPack := rootProgram.AllPackages()
	for pkgIdx := range allPack {
		pkg := allPack[pkgIdx]
		for mName, mem := range pkg.Members {
			if mem.Token() == token.VAR {
				glob := mem.(*ssa.Global)
				pName := glob.Pkg.Object.Name()
				//println("DEBUG processing global:", pName, mName)
				posStr := CodePosition(glob.Pos())
				MakePosHash(glob.Pos()) // mark that we are dealing with this global
				if IsValidInPogo(
					glob.Type().(*types.Pointer).Elem(), // globals are always pointers to a global
					"Global:"+pName+"."+mName+":"+posStr) {
					if !hadErrors { // no point emitting code if we have already encounderd an error
						isPublic := unicode.IsUpper(rune(mName[0])) // Object value sometimes not available
						l := TargetLang
						_, _, isOverloaded := LanguageList[l].PackageOverloaded(pName)
						if !isOverloaded &&
							!(mName == "init$guard" && strings.HasPrefix(glob.RelString(nil), LibRuntimePath) && isDupPkg(pName)) {
							fmt.Fprintln(&LanguageList[l].buffer, LanguageList[l].Global(pName, mName, *glob, posStr, isPublic))
						}
					}
				}
			}
		}
	}
}
Example #27
0
func isExported(name string) bool {
	if name != "" {
		r, _ := utf8.DecodeRuneInString(name)
		return r != utf8.RuneError && unicode.IsUpper(r)
	}
	return false
}
Example #28
0
// Emit the Global declarations, run inside the Go class declaration output.
func emitGlobals() {
	allPack := rootProgram.AllPackages()
	sort.Sort(PackageSorter(allPack))
	for pkgIdx := range allPack {
		pkg := allPack[pkgIdx]
		allMem := MemberNamesSorted(pkg)
		for _, mName := range allMem {
			mem := pkg.Members[mName]
			if mem.Token() == token.VAR {
				glob := mem.(*ssa.Global)
				pName := glob.Pkg.Object.Path() // was .Name()
				//println("DEBUG processing global:", pName, mName)
				posStr := CodePosition(glob.Pos())
				MakePosHash(glob.Pos()) // mark that we are dealing with this global
				if IsValidInPogo(
					glob.Type().(*types.Pointer).Elem(), // globals are always pointers to a global
					"Global:"+pName+"."+mName+":"+posStr) {
					if !hadErrors { // no point emitting code if we have already encounderd an error
						isPublic := unicode.IsUpper(rune(mName[0])) // Object value sometimes not available
						l := TargetLang
						fmt.Fprintln(&LanguageList[l].buffer, LanguageList[l].Global(pName, mName, *glob, posStr, isPublic))
					}
				}
			}
		}
	}
}
Example #29
0
// lintName returns a different name if it should be different.
func lintName(name string) (should string) {
	// Fast path for simple cases: "_" and all lowercase.
	if name == "_" {
		return name
	}
	allLower := true
	for _, r := range name {
		if !unicode.IsLower(r) {
			allLower = false
			break
		}
	}
	if allLower {
		return name
	}

	// Split camelCase at any lower->upper transition, and split on underscores.
	// Check each word for common initialisms.
	runes := []rune(name)
	w, i := 0, 0 // index of start of word, scan
	for i+1 <= len(runes) {
		eow := false // whether we hit the end of a word
		if i+1 == len(runes) {
			eow = true
		} else if runes[i+1] == '_' {
			// underscore; shift the remainder forward over any run of underscores
			eow = true
			n := 1
			for i+n+1 < len(runes) && runes[i+n+1] == '_' {
				n++
			}
			copy(runes[i+1:], runes[i+n+1:])
			runes = runes[:len(runes)-n]
		} else if unicode.IsLower(runes[i]) && unicode.IsUpper(runes[i+1]) {
			// lower->upper
			eow = true
		}
		i++
		if !eow {
			continue
		}

		// [w,i) is a word.
		word := string(runes[w:i])
		if u := strings.ToUpper(word); commonInitialisms[u] {
			// Keep consistent case, which is lowercase only at the start.
			if w == 0 && unicode.IsLower(runes[w]) {
				u = strings.ToLower(u)
			}
			// All the common initialisms are ASCII,
			// so we can replace the bytes exactly.
			copy(runes[w:], []rune(u))
		} else if w > 0 && strings.ToLower(word) == word {
			// already all lowercase, and not the first word, so uppercase the first character.
			runes[w] = unicode.ToUpper(runes[w])
		}
		w = i
	}
	return string(runes)
}
Example #30
0
func NewChain(r io.Reader, prefixSize int) (c *Chain, err error) {
	input, err := ioutil.ReadAll(r)
	if err != nil {
		return nil, err
	}

	words := strings.Fields(string(input))

	c = &Chain{}
	c.prefixes = make([]Prefix, 0)
	c.chain = make(map[string][]string)

	for i := 0; i < len(words)-prefixSize; i++ {
		prefix := Prefix(words[i : i+prefixSize])
		c.Add(prefix, words[i+prefixSize])
		c.prefixes = append(c.prefixes, prefix)
		if unicode.IsUpper(rune(prefix[0][0])) {
			c.starters = append(c.starters, prefix)
		}
	}

	if len(c.starters) == 0 {
		c.starters = c.prefixes
	}

	return c, nil
}