-
Notifications
You must be signed in to change notification settings - Fork 0
/
vocabulary.go
129 lines (109 loc) · 2.79 KB
/
vocabulary.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package vocabulary
import (
"errors"
"fmt"
"io/fs"
"sort"
"strings"
"unicode"
"unicode/utf8"
"github.com/spf13/viper"
)
const (
configFile = "vocabulary"
configLanguages = "languages"
defaultLanguage = "default"
defaultDirectory = "todo/vocabulary"
generatedMessage = "This file was generated by github.com/leonhfr/vocabulary-action and is susceptible to be modified by automations."
summaryLength = 10
)
func LanguageDirectory(language string, config map[string]string) string {
directory, ok := config[language]
if ok {
return directory
}
directory, ok = config[defaultLanguage]
if ok {
return directory
}
return defaultDirectory
}
func ParseConfig(workspace string) map[string]string {
viper.AddConfigPath(workspace)
viper.SetConfigName(configFile)
err := viper.ReadInConfig()
if err != nil {
return map[string]string{}
}
return viper.GetStringMapString(configLanguages)
}
func Filter(paragraphs []string) (accepted []string, discarded []string) {
for _, p := range paragraphs {
if _, ok := firstRuneIsLetter(p); ok {
accepted = append(accepted, p)
} else {
discarded = append(discarded, p)
}
}
return
}
func Buckets(vocabulary []string) map[rune][]string {
buckets := map[rune][]string{}
for _, word := range vocabulary {
if r, ok := firstRuneIsLetter(word); ok {
buckets[r] = append(buckets[r], word)
}
}
return buckets
}
func Existing(dir, filename string, fh FileHandler) (string, error) {
contents, err := fh.Read(dir, filename)
if errors.Is(err, fs.ErrNotExist) {
return "", nil
}
return contents, err
}
func Merge(old, new []string) []string {
next := append(old, new...)
alphabeticalSort(next)
return next
}
func Upsert(dir, filename string, r rune, vocabulary []string, fh FileHandler) error {
contents := fmt.Sprintf("<!-- %s -->\n\n# %c\n\n%s\n", generatedMessage, r, strings.Join(vocabulary, "\n\n"))
return fh.Write(dir, filename, contents)
}
func Summary(vocabulary []string) string {
alphabeticalSort(vocabulary)
summary := make([]string, 0, len(vocabulary))
for _, line := range vocabulary {
var word []string
for _, f := range strings.Fields(line) {
if _, ok := firstRuneIsLetter(f); !ok {
break
}
word = append(word, f)
}
summary = append(summary, strings.Join(word, " "))
}
if len(summary) < summaryLength {
return strings.Join(summary, ", ")
}
return strings.Join(summary[:summaryLength], ", ")
}
func alphabeticalSort(slice []string) {
sort.Slice(slice, func(i, j int) bool {
li := strings.ToLower(slice[i])
lj := strings.ToLower(slice[j])
if li == lj {
return slice[i] < slice[j]
}
return li < lj
})
}
func firstRuneIsLetter(line string) (rune, bool) {
r, _ := utf8.DecodeRuneInString(line)
if r == utf8.RuneError {
return 0, false
}
return unicode.ToLower(r), unicode.IsLetter(r)
}