runewidth_posix.go 1.3 KB

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