aboutsummaryrefslogtreecommitdiff
path: root/games/syl
blob: d83187c6cba3e7159275d127ed66060f2043bcf7 (plain) (blame)
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
#!/usr/bin/env bash

# Apply some dumb heuristics to guess at the number of syllables in the English
# word given as the sole required argument
word=${1:?Need a word}
lcword=$(printf %s "$word" | tr '[:upper:]' '[:lower:]')

# Start counting syllables for the word and vowels for the current vowel group
declare -i sylc vowc

# Iterate through the letters in the word
for ((i = 0; i < ${#word}; i++)); do
    case ${word:i:1} in

        # If it's a vowel or a y, we might be adding a syllable. We here
        # include all the vowels I got out of /usr/share/dict/words on my
        # system.
        [aeiouyáâäåèéêíóôöûü])

            # Bump the number of vowels so far in this group
            ((vowc++))

            # On every odd vowel, we'll add another syllable, so that "e" and
            # "ei" are each one syllable, but "eia" and "eiau" are two.
            ((vowc % 2)) && ((sylc++))
            ;;

        # If it's not a vowel or a y, reset the vowel count
        *)
            ((vowc = 0))
            ;;
    esac
done

# As a special case, if the word ends with a consonant and then "e" and has
# more than one syllable, subtract one syllable as it's probably a silent "e"
if ((sylc > 1)) ; then
    case $lcword in

        # Exceptions first
        *[bcdgptx]le|*c[mn]e|*phe)
            ;;
        *[!aeiouy]e)
            ((sylc--))
            ;;

        # "pined", "loved", but not "wasted", "devoted"
        *[bcdgptx]led)
            ;;
        *[!aeiotuy]ed)
            ((sylc--))
            ;;

        # Plural forms of the above
        *[bc]les|*c[mn]es|*phes)
            ;;
        *[!aeiousy]es)
            ((sylc--))
            ;;
    esac
fi

# Add a syllable for an "ism" suffix
case $lcword in
    *ism|*isms)
        ((sylc++))
        ;;
esac

# Print the determined syllable count
printf '%u\n' "$sylc"