4 Commits

9 changed files with 232 additions and 141 deletions

View File

@@ -58,6 +58,7 @@ Since the PineTime does not have enough space to store all unicode glyphs, it on
- French - French
- Armenian - Armenian
- Korean - Korean
- Chinese
- Emoji - Emoji
Place the desired map names in an array as `notifs.translit.use`. They will be evaluated in order. You can also put custom transliterations in `notifs.translit.custom`. These take priority over any other maps. The `notifs.translit` config section should look like this: Place the desired map names in an array as `notifs.translit.use`. They will be evaluated in order. You can also put custom transliterations in `notifs.translit.custom`. These take priority over any other maps. The `notifs.translit` config section should look like this:

1
go.mod
View File

@@ -15,6 +15,7 @@ require (
github.com/mattn/go-isatty v0.0.13 // indirect github.com/mattn/go-isatty v0.0.13 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mitchellh/mapstructure v1.4.1 github.com/mitchellh/mapstructure v1.4.1
github.com/mozillazg/go-pinyin v0.18.0
github.com/rs/zerolog v1.23.0 github.com/rs/zerolog v1.23.0
github.com/sirupsen/logrus v1.8.1 // indirect github.com/sirupsen/logrus v1.8.1 // indirect
github.com/spf13/cast v1.4.1 // indirect github.com/spf13/cast v1.4.1 // indirect

2
go.sum
View File

@@ -242,6 +242,8 @@ github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mozillazg/go-pinyin v0.18.0 h1:hQompXO23/0ohH8YNjvfsAITnCQImCiR/Fny8EhIeW0=
github.com/mozillazg/go-pinyin v0.18.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc=
github.com/muka/go-bluetooth v0.0.0-20210812063148-b6c83362e27d h1:EG/xyWjHT19rkUpwsWSkyiCCmyqNwFovr9m10rhyOxU= github.com/muka/go-bluetooth v0.0.0-20210812063148-b6c83362e27d h1:EG/xyWjHT19rkUpwsWSkyiCCmyqNwFovr9m10rhyOxU=
github.com/muka/go-bluetooth v0.0.0-20210812063148-b6c83362e27d/go.mod h1:dMCjicU6vRBk34dqOmIZm0aod6gUwZXOXzBROqGous0= github.com/muka/go-bluetooth v0.0.0-20210812063148-b6c83362e27d/go.mod h1:dMCjicU6vRBk34dqOmIZm0aod6gUwZXOXzBROqGous0=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=

View File

@@ -73,7 +73,7 @@ func initNotifRelay(dev *infinitime.Device) error {
} }
maps := viper.GetStringSlice("notifs.translit.use") maps := viper.GetStringSlice("notifs.translit.use")
translit.Maps["custom"] = translit.Map(viper.GetStringSlice("notifs.translit.custom")) translit.Transliterators["custom"] = translit.Map(viper.GetStringSlice("notifs.translit.custom"))
sender = translit.Transliterate(sender, maps...) sender = translit.Transliterate(sender, maps...)
summary = translit.Transliterate(summary, maps...) summary = translit.Transliterate(summary, maps...)
body = translit.Transliterate(body, maps...) body = translit.Transliterate(body, maps...)

View File

@@ -171,7 +171,7 @@ func handleConnection(conn net.Conn, dev *infinitime.Device) {
break break
} }
maps := viper.GetStringSlice("notifs.translit.use") maps := viper.GetStringSlice("notifs.translit.use")
translit.Maps["custom"] = translit.Map(viper.GetStringSlice("notifs.translit.custom")) translit.Transliterators["custom"] = translit.Map(viper.GetStringSlice("notifs.translit.custom"))
title := translit.Transliterate(reqData.Title, maps...) title := translit.Transliterate(reqData.Title, maps...)
body := translit.Transliterate(reqData.Body, maps...) body := translit.Transliterate(reqData.Body, maps...)
// Send notification to watch // Send notification to watch

138
translit/armenian.go Normal file
View File

@@ -0,0 +1,138 @@
package translit
import (
"strings"
)
type ArmenianTranslit struct{}
var armenianMap = []string{
"աու", "au",
"բու", "bu",
"գու", "gu",
"դու", "du",
"եու", "eu",
"զու", "zu",
"էու", "eu",
"ըու", "yu",
"թու", "tu",
"ժու", "ju",
"իու", "iu",
"լու", "lu",
"խու", "xu",
"ծու", "cu",
"կու", "ku",
"հու", "hu",
"ձու", "dzu",
"ղու", "xu",
"ճու", "cu",
"մու", "mu",
"յու", "yu",
"նու", "nu",
"շու", "shu",
"չու", "chu",
"պու", "pu",
"ջու", "ju",
"ռու", "ru",
"սու", "su",
"վու", "vu",
"տու", "tu",
"րու", "ru",
"ցու", "cu",
"փու", "pu",
"քու", "qu",
"օու", "ou",
"ևու", "eu",
"ֆու", "fu",
"ոու", "vou",
"ու", "u",
"բո", "bo",
"գո", "go",
"դո", "do",
"զո", "zo",
"թո", "to",
"ժո", "jo",
"լո", "lo",
"խո", "xo",
"ծո", "co",
"կո", "ko",
"հո", "ho",
"ձո", "dzo",
"ղո", "xo",
"ճո", "co",
"մո", "mo",
"յո", "yo",
"նո", "no",
"շո", "so",
"չո", "co",
"պո", "po",
"ջո", "jo",
"ռո", "ro",
"սո", "so",
"վո", "vo",
"տո", "to",
"րո", "ro",
"ցո", "co",
"փո", "po",
"քո", "qo",
"ևո", "eo",
"ֆո", "fo",
"ո", "vo",
"եւ", "ev",
"եվ", "ev",
"ա", "a",
"բ", "b",
"գ", "g",
"դ", "d",
"ե", "e",
"զ", "z",
"է", "e",
"ը", "y",
"թ", "t",
"ժ", "j",
"ի", "i",
"լ", "l",
"խ", "x",
"ծ", "c",
"կ", "k",
"հ", "h",
"ձ", "dz",
"ղ", "x",
"ճ", "c",
"մ", "m",
"յ", "y",
"ն", "n",
"շ", "sh",
"չ", "ch",
"պ", "p",
"ջ", "j",
"ռ", "r",
"ս", "s",
"վ", "v",
"տ", "t",
"ր", "r",
"ց", "c",
"փ", "p",
"ք", "q",
"օ", "o",
"և", "ev",
"ֆ", "f",
"ւ", "",
}
func init() {
lower := armenianMap
for i, val := range lower {
if i%2 == 1 {
continue
}
capital := strings.Title(val)
if capital != val {
armenianMap = append(armenianMap, capital, strings.Title(armenianMap[i+1]))
}
}
}
func (at *ArmenianTranslit) Transliterate(s string) string {
return strings.NewReplacer(armenianMap...).Replace(s)
}

42
translit/chinese.go Normal file
View File

@@ -0,0 +1,42 @@
package translit
import (
"bytes"
"strings"
"unicode"
"github.com/mozillazg/go-pinyin"
)
// ChineseTranslit implements Transliterator using a pinyin
// conversion library.
type ChineseTranslit struct{}
func (ct *ChineseTranslit) Transliterate(s string) string {
// Create buffer for final output
outBuf := &bytes.Buffer{}
// Create buffer to temporarily store chinese characters
tmpBuf := &bytes.Buffer{}
// For every character in string
for _, char := range s {
// If character in Han range
if unicode.Is(unicode.Han, char) {
// Write character to temporary buffer
tmpBuf.WriteRune(char)
} else {
// If buffer contains characters
if tmpBuf.Len() > 0 {
// Convert to pinyin (without tones)
out := pinyin.LazyConvert(tmpBuf.String(), nil)
// Write space-separated string to output
outBuf.WriteString(strings.Join(out, " "))
// Reset temporary buffer
tmpBuf.Reset()
}
// Write character to output
outBuf.WriteRune(char)
}
}
// Return output string
return outBuf.String()
}

View File

@@ -294,10 +294,14 @@ func translitSpecialProvisions(previousEnding rune, nextInitial rune) (string, b
switch previousEnding { switch previousEnding {
case 0x11A8: case 0x11A8:
return "ngn", true // ㄱ return "ngn", true // ㄱ
case 0x11AE: // ㄷ case 0x11AE:
case 0x11BA: // fallthrough //
case 0x11BD: // ㅈ case 0x11BA:
case 0x11BE: // fallthrough //
case 0x11BD:
fallthrough // ㅈ
case 0x11BE:
fallthrough // ㅊ
case 0x11C0: // ㅌ case 0x11C0: // ㅌ
return "nn", true return "nn", true
case 0x11AF: case 0x11AF:
@@ -309,17 +313,24 @@ func translitSpecialProvisions(previousEnding rune, nextInitial rune) (string, b
} }
case 0x1105: // ㄹ case 0x1105: // ㄹ
switch previousEnding { switch previousEnding {
case 0x11A8: // ㄱ case 0x11A8:
case 0x11AB: // fallthrough //
case 0x11AB:
fallthrough // ㄴ
case 0x11AF: // ㄹ case 0x11AF: // ㄹ
return "ll", true return "ll", true
case 0x11AE: // ㄷ case 0x11AE:
case 0x11BA: // fallthrough //
case 0x11BD: // ㅈ case 0x11BA:
case 0x11BE: // fallthrough //
case 0x11BD:
fallthrough // ㅈ
case 0x11BE:
fallthrough // ㅊ
case 0x11C0: // ㅌ case 0x11C0: // ㅌ
return "nn", true return "nn", true
case 0x11B7: // ㅁ case 0x11B7:
fallthrough // ㅁ
case 0x11B8: // ㅂ case 0x11B8: // ㅂ
return "mn", true return "mn", true
case 0x11BC: case 0x11BC:
@@ -331,10 +342,14 @@ func translitSpecialProvisions(previousEnding rune, nextInitial rune) (string, b
switch previousEnding { switch previousEnding {
case 0x11A8: case 0x11A8:
return "ngm", true // ㄱ return "ngm", true // ㄱ
case 0x11AE: // ㄷ case 0x11AE:
case 0x11BA: // fallthrough //
case 0x11BD: // ㅈ case 0x11BA:
case 0x11BE: // fallthrough //
case 0x11BD:
fallthrough // ㅈ
case 0x11BE:
fallthrough // ㅊ
case 0x11C0: // ㅌ case 0x11C0: // ㅌ
return "nm", true return "nm", true
case 0x11B8: case 0x11B8:
@@ -372,10 +387,14 @@ func translitSpecialProvisions(previousEnding rune, nextInitial rune) (string, b
} }
case 0x1110: // ㅌ case 0x1110: // ㅌ
switch previousEnding { switch previousEnding {
case 0x11AE: // ㄷ case 0x11AE:
case 0x11BA: // fallthrough //
case 0x11BD: // ㅈ case 0x11BA:
case 0x11BE: // fallthrough //
case 0x11BD:
fallthrough // ㅈ
case 0x11BE:
fallthrough // ㅊ
case 0x11C0: // ㅌ case 0x11C0: // ㅌ
return "t-t", true return "t-t", true
default: default:
@@ -391,7 +410,6 @@ func translitSpecialProvisions(previousEnding rune, nextInitial rune) (string, b
default: default:
return "", false return "", false
} }
return "", false
} }
// Decompose a syllable into several jamo. Does nothing if that isn't possible. // Decompose a syllable into several jamo. Does nothing if that isn't possible.

View File

@@ -9,7 +9,7 @@ func Transliterate(s string, useMaps ...string) string {
// Create variable to store modified string // Create variable to store modified string
out := s out := s
// If custom map exists // If custom map exists
if customMap, ok := Maps["custom"]; ok { if customMap, ok := Transliterators["custom"]; ok {
// Perform transliteration with it // Perform transliteration with it
out = customMap.Transliterate(out) out = customMap.Transliterate(out)
} }
@@ -20,7 +20,7 @@ func Transliterate(s string, useMaps ...string) string {
continue continue
} }
// Get requested map // Get requested map
translitMap, ok := Maps[useMap] translitMap, ok := Transliterators[useMap]
if !ok { if !ok {
continue continue
} }
@@ -47,9 +47,9 @@ func (mt Map) Transliterate(s string) string {
return strings.NewReplacer(mt...).Replace(s) return strings.NewReplacer(mt...).Replace(s)
} }
// Maps stores transliteration maps as slices to preserve order. // Transliterators stores transliterator implementations for each supported language.
// Some of these maps were sourced from https://codeberg.org/Freeyourgadget/Gadgetbridge // Some of these were sourced from https://codeberg.org/Freeyourgadget/Gadgetbridge
var Maps = map[string]Transliterator{ var Transliterators = map[string]Transliterator{
"eASCII": Map{ "eASCII": Map{
"œ", "oe", "œ", "oe",
"ª", "a", "ª", "a",
@@ -323,119 +323,6 @@ var Maps = map[string]Transliterator{
"ÿ", "y", "ÿ", "y",
"ç", "c", "ç", "c",
}, },
"Armenian": Map{
"աու", "au",
"բու", "bu",
"գու", "gu",
"դու", "du",
"եու", "eu",
"զու", "zu",
"էու", "eu",
"ըու", "yu",
"թու", "tu",
"ժու", "ju",
"իու", "iu",
"լու", "lu",
"խու", "xu",
"ծու", "cu",
"կու", "ku",
"հու", "hu",
"ձու", "dzu",
"ղու", "xu",
"ճու", "cu",
"մու", "mu",
"յու", "yu",
"նու", "nu",
"շու", "shu",
"չու", "chu",
"պու", "pu",
"ջու", "ju",
"ռու", "ru",
"սու", "su",
"վու", "vu",
"տու", "tu",
"րու", "ru",
"ցու", "cu",
"փու", "pu",
"քու", "qu",
"օու", "ou",
"ևու", "eu",
"ֆու", "fu",
"ոու", "vou",
"ու", "u",
"բո", "bo",
"գո", "go",
"դո", "do",
"զո", "zo",
"թո", "to",
"ժո", "jo",
"լո", "lo",
"խո", "xo",
"ծո", "co",
"կո", "ko",
"հո", "ho",
"ձո", "dzo",
"ղո", "xo",
"ճո", "co",
"մո", "mo",
"յո", "yo",
"նո", "no",
"շո", "so",
"չո", "co",
"պո", "po",
"ջո", "jo",
"ռո", "ro",
"սո", "so",
"վո", "vo",
"տո", "to",
"րո", "ro",
"ցո", "co",
"փո", "po",
"քո", "qo",
"ևո", "eo",
"ֆո", "fo",
"ո", "vo",
"եւ", "ev",
"եվ", "ev",
"ա", "a",
"բ", "b",
"գ", "g",
"դ", "d",
"ե", "e",
"զ", "z",
"է", "e",
"ը", "y",
"թ", "t",
"ժ", "j",
"ի", "i",
"լ", "l",
"խ", "x",
"ծ", "c",
"կ", "k",
"հ", "h",
"ձ", "dz",
"ղ", "x",
"ճ", "c",
"մ", "m",
"յ", "y",
"ն", "n",
"շ", "sh",
"չ", "ch",
"պ", "p",
"ջ", "j",
"ռ", "r",
"ս", "s",
"վ", "v",
"տ", "t",
"ր", "r",
"ց", "c",
"փ", "p",
"ք", "q",
"օ", "o",
"և", "ev",
"ֆ", "f",
"ւ", "",
},
"Emoji": Map{ "Emoji": Map{
"😂", ":')", "😂", ":')",
"😊", ":)", "😊", ":)",
@@ -465,4 +352,6 @@ var Maps = map[string]Transliterator{
"💤", ":zzz:", "💤", ":zzz:",
}, },
"Korean": &KoreanTranslit{}, "Korean": &KoreanTranslit{},
"Chinese": &ChineseTranslit{},
"Armenian": &ArmenianTranslit{},
} }