package trans import ( "fmt" "os/exec" "strings" "regexp" ) type Translation struct { word string fromLang string toLang string Executor func(*Translation) ([]byte, error) } func New(word, fromLang, toLang string) Translation { return Translation{ word: word, fromLang: fromLang, toLang: toLang, Executor: executeTransShell, } } func executeTransShell(t *Translation) ([]byte, error) { config := []string{ "-no-ansi", "-show-original", "n", "-show-original-phonetics", "n", "-show-dictionary", "y", "-show-languages", "n", "-show-prompt-message", "n", fmt.Sprintf("%s:%s", t.fromLang, t.toLang), t.word, } return exec.Command("trans", config...).Output() } func (t Translation) Translate() []string { outBytes, err := t.Executor(&t) if err != nil { panic(err) } return uniqueSlice(parseTransOutput(string(outBytes))) } func parseTransOutput(out string) []string { re := regexp.MustCompile(`(?m)^\s{4}\w.*$`) lineMatches := re.FindAllString(out, -1) results := []string{strings.Split(out, "\n")[0]} for _, line := range lineMatches { for _, word := range strings.Split(strings.TrimSpace(line), ",") { results = append(results, strings.TrimSpace(word)) } } return results } func uniqueSlice(items []string) []string { encountered := map[string]bool{} uniqueSlice := []string{} for _, item := range items { if !encountered[item] { encountered[item] = true uniqueSlice = append(uniqueSlice, item) } } return uniqueSlice }