runewidth_posix.go (1481B)
1 //go:build !windows && !js && !appengine 2 // +build !windows,!js,!appengine 3 4 package runewidth 5 6 import ( 7 "os" 8 "regexp" 9 "strings" 10 ) 11 12 var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`) 13 14 var mblenTable = map[string]int{ 15 "utf-8": 6, 16 "utf8": 6, 17 "jis": 8, 18 "eucjp": 3, 19 "euckr": 2, 20 "euccn": 2, 21 "sjis": 2, 22 "cp932": 2, 23 "cp51932": 2, 24 "cp936": 2, 25 "cp949": 2, 26 "cp950": 2, 27 "big5": 2, 28 "gbk": 2, 29 "gb2312": 2, 30 } 31 32 func isEastAsian(locale string) bool { 33 charset := strings.ToLower(locale) 34 r := reLoc.FindStringSubmatch(locale) 35 if len(r) == 2 { 36 charset = strings.ToLower(r[1]) 37 } 38 39 if strings.HasSuffix(charset, "@cjk_narrow") { 40 return false 41 } 42 43 for pos, b := range []byte(charset) { 44 if b == '@' { 45 charset = charset[:pos] 46 break 47 } 48 } 49 max := 1 50 if m, ok := mblenTable[charset]; ok { 51 max = m 52 } 53 if max > 1 && (charset[0] != 'u' || 54 strings.HasPrefix(locale, "ja") || 55 strings.HasPrefix(locale, "ko") || 56 strings.HasPrefix(locale, "zh")) { 57 return true 58 } 59 return false 60 } 61 62 // IsEastAsian return true if the current locale is CJK 63 func IsEastAsian() bool { 64 locale := os.Getenv("LC_ALL") 65 if locale == "" { 66 locale = os.Getenv("LC_CTYPE") 67 } 68 if locale == "" { 69 locale = os.Getenv("LANG") 70 } 71 72 // ignore C locale 73 if locale == "POSIX" || locale == "C" { 74 return false 75 } 76 if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') { 77 return false 78 } 79 80 return isEastAsian(locale) 81 }