From 73f16fcfefca7d43ef6636655bb0f2e48027e7bb Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Mon, 4 Oct 2021 17:45:26 -0700 Subject: [PATCH] Use interface to allow for more complex transliteration implementations --- notifs.go | 9 ++-- socket.go | 7 ++-- translit/translit.go | 97 ++++++++++++++++++++++++++++---------------- 3 files changed, 69 insertions(+), 44 deletions(-) diff --git a/notifs.go b/notifs.go index 23d2768..52c04d5 100644 --- a/notifs.go +++ b/notifs.go @@ -73,11 +73,10 @@ func initNotifRelay(dev *infinitime.Device) error { } maps := viper.GetStringSlice("notifs.translit.maps.use") - translit.Maps["custom"] = viper.GetStringSlice("notifs.translit.maps.custom") - replacer := translit.NewReplacer(maps...) - sender = replacer.Replace(sender) - summary = replacer.Replace(summary) - body = replacer.Replace(body) + translit.Maps["custom"] = translit.Map(viper.GetStringSlice("notifs.translit.maps.custom")) + sender = translit.Transliterate(sender, maps...) + summary = translit.Transliterate(summary, maps...) + body = translit.Transliterate(body, maps...) var msg string // If summary does not exist, set message to body. diff --git a/socket.go b/socket.go index ccc3e5c..32c5fc8 100644 --- a/socket.go +++ b/socket.go @@ -171,10 +171,11 @@ func handleConnection(conn net.Conn, dev *infinitime.Device) { break } maps := viper.GetStringSlice("notifs.translit.maps.use") - translit.Maps["custom"] = viper.GetStringSlice("notifs.translit.maps.custom") - replacer := translit.NewReplacer(maps...) + translit.Maps["custom"] = translit.Map(viper.GetStringSlice("notifs.translit.maps.custom")) + title := translit.Transliterate(reqData.Title, maps...) + body := translit.Transliterate(reqData.Body, maps...) // Send notification to watch - err = dev.Notify(replacer.Replace(reqData.Title), replacer.Replace(reqData.Body)) + err = dev.Notify(title, body) if err != nil { connErr(conn, err, "Error sending notification") break diff --git a/translit/translit.go b/translit/translit.go index ad3f4b8..a116d87 100644 --- a/translit/translit.go +++ b/translit/translit.go @@ -4,17 +4,60 @@ import ( "strings" ) +// Transliterate runs the given maps on s and returns the result +func Transliterate(s string, useMaps ...string) string { + // Create variable to store modified string + out := s + // If custom map exists + if customMap, ok := Maps["custom"]; ok { + // Perform transliteration with it + out = customMap.Transliterate(out) + } + // For every map to use + for _, useMap := range useMaps { + // If custom, skip + if useMap == "custom" { + continue + } + // Get requested map + translitMap, ok := Maps[useMap] + if !ok { + continue + } + // Perform transliteration + out = translitMap.Transliterate(out) + } + // Return result + return out +} + +// Transliterator is implemented by anything with a +// Transliterate method, which performs transliteration +// and returns the resulting string. +type Transliterator interface { + Transliterate(string) string +} + +// Map implements Transliterator using a slice where +// every odd element is a key and every even one is a value +// which replaces the key. +type Map []string + +func (mt Map) Transliterate(s string) string { + return strings.NewReplacer(mt...).Replace(s) +} + // Maps stores transliteration maps as slices to preserve order. // Some of these maps were sourced from https://codeberg.org/Freeyourgadget/Gadgetbridge -var Maps = map[string][]string{ - "eASCII": { +var Maps = map[string]Transliterator{ + "eASCII": Map{ "œ", "oe", "ª", "a", "°", "o", "«", `"`, "»", `"`, }, - "Scandinavian": { + "Scandinavian": Map{ "Æ", "Ae", "æ", "ae", "Ø", "Oe", @@ -22,7 +65,7 @@ var Maps = map[string][]string{ "Å", "Aa", "å", "aa", }, - "German": { + "German": Map{ "ä", "ae", "ö", "oe", "ü", "ue", @@ -32,7 +75,7 @@ var Maps = map[string][]string{ "ß", "ss", "ẞ", "SS", }, - "Hebrew": { + "Hebrew": Map{ "א", "a", "ב", "b", "ג", "g", @@ -61,7 +104,7 @@ var Maps = map[string][]string{ "ם", "m", "ן", "n", }, - "Greek": { + "Greek": Map{ "α", "a", "ά", "a", "β", "v", @@ -132,11 +175,11 @@ var Maps = map[string][]string{ "Ω", "O", "Ώ", "O", }, - "Russian": { + "Russian": Map{ "Ё", "Йo", "ё", "йo", }, - "Ukranian": { + "Ukranian": Map{ "ґ", "gh", "є", "je", "і", "i", @@ -146,7 +189,7 @@ var Maps = map[string][]string{ "І", "I", "Ї", "JI", }, - "Arabic": { + "Arabic": Map{ "ا", "a", "ب", "b", "ت", "t", @@ -194,7 +237,7 @@ var Maps = map[string][]string{ "٨", "8", "٩", "9", }, - "Farsi": { + "Farsi": Map{ "پ", "p", "چ", "ch", "ژ", "zh", @@ -223,11 +266,11 @@ var Maps = map[string][]string{ "ُ", "o", "ّ", "", }, - "Polish": { + "Polish": Map{ "Ł", "L", "ł", "l", }, - "Lithuanian": { + "Lithuanian": Map{ "ą", "a", "č", "c", "ę", "e", @@ -238,7 +281,7 @@ var Maps = map[string][]string{ "ū", "u", "ž", "z", }, - "Estonian": { + "Estonian": Map{ "ä", "a", "Ä", "A", "ö", "o", @@ -248,13 +291,13 @@ var Maps = map[string][]string{ "ü", "u", "Ü", "U", }, - "Icelandic": { + "Icelandic": Map{ "Þ", "Th", "þ", "th", "Ð", "D", "ð", "d", }, - "Czeck": { + "Czeck": Map{ "ř", "r", "ě", "e", "ý", "y", @@ -268,7 +311,7 @@ var Maps = map[string][]string{ "ť", "t", "ň", "n", }, - "French": { + "French": Map{ "à", "a", "â", "a", "é", "e", @@ -280,7 +323,7 @@ var Maps = map[string][]string{ "ÿ", "y", "ç", "c", }, - "Armenian": { + "Armenian": Map{ "աու", "au", "բու", "bu", "գու", "gu", @@ -393,7 +436,7 @@ var Maps = map[string][]string{ "ֆ", "f", "ւ", "", }, - "Emoji": { + "Emoji": Map{ "😂", ":')", "😊", ":)", "😃", ":)", @@ -422,21 +465,3 @@ var Maps = map[string][]string{ "💤", ":zzz:", }, } - -func NewReplacer(useMaps ...string) *strings.Replacer { - var replace []string - if customMap, ok := Maps["custom"]; ok { - replace = append(replace, customMap...) - } - for _, useMap := range useMaps { - if useMap == "custom" { - continue - } - translitMap, ok := Maps[useMap] - if !ok { - continue - } - replace = append(replace, translitMap...) - } - return strings.NewReplacer(replace...) -}