94 lines
2.3 KiB
TypeScript
94 lines
2.3 KiB
TypeScript
const vowels = ['A', 'E', 'I', 'O', 'U']
|
|
const consonants = [
|
|
'B',
|
|
'C',
|
|
'D',
|
|
'F',
|
|
'G',
|
|
'H',
|
|
'J',
|
|
'K',
|
|
'L',
|
|
'M',
|
|
'N',
|
|
'P',
|
|
'Q',
|
|
'R',
|
|
'S',
|
|
'T',
|
|
'V',
|
|
'W',
|
|
'X',
|
|
'Y',
|
|
'Z',
|
|
]
|
|
|
|
const startsWiths = ['XR', 'YT', 'AY']
|
|
|
|
const rule1 = (word: string) =>
|
|
// If a word begins with a vowel, or starts with `"xr"` or `"yt"`,
|
|
// add an `"ay"` sound to the end of the word.
|
|
vowels.concat(startsWiths).some(s => word.toUpperCase().startsWith(s))
|
|
? `${word}ay`
|
|
: word
|
|
|
|
const rule2RegExp = new RegExp(`^([${consonants.join('')}]+)(.*)`, 'i')
|
|
|
|
const rule2 = (word: string): string =>
|
|
// If a word begins with a one or more consonants, first move
|
|
// those consonants to the end of the word and then add an `"ay"`
|
|
// sound to the end of the word.
|
|
word.replace(
|
|
rule2RegExp,
|
|
(_, match, rest) => `${rest}${match}${match ? 'ay' : ''}`,
|
|
)
|
|
|
|
const rule3RegExp = new RegExp(`^(qu|[${consonants.join('')}]*qu)(.*)`, 'i')
|
|
|
|
const rule3 = (word: string): string =>
|
|
// If a word starts with zero or more consonants followed by `"qu"`,
|
|
// first move those consonants (if any) and the `"qu"` part to the end
|
|
// of the word, and then add an `"ay"` sound to the end of the word.
|
|
word.replace(
|
|
rule3RegExp,
|
|
(_, match, rest) => `${rest}${match}${match ? 'ay' : ''}`,
|
|
)
|
|
|
|
const rule4RegExp = new RegExp(`^([${consonants.join('')}]+)(y.*)`, 'i')
|
|
|
|
const rule4 = (word: string): string =>
|
|
// If a word starts with one or more consonants followed by `"y"`,
|
|
// first move the consonants preceding the `"y"`to the end of the word,
|
|
// and then add an `"ay"` sound to the end of the word.
|
|
word.replace(
|
|
rule4RegExp,
|
|
(_, match, rest) => `${rest}${match}${match ? 'ay' : ''}`,
|
|
)
|
|
|
|
const applyRule =
|
|
(rule: (word: string) => string) =>
|
|
({
|
|
originalWord,
|
|
hasChanged,
|
|
}: {
|
|
originalWord: string
|
|
hasChanged: boolean
|
|
}) => {
|
|
if (hasChanged) return { originalWord, hasChanged }
|
|
const word = rule(originalWord)
|
|
return { originalWord: word, hasChanged: word !== originalWord }
|
|
}
|
|
|
|
export const translate = (text: string): string => {
|
|
return text
|
|
.split(' ')
|
|
.filter(Boolean)
|
|
.map(word => ({ originalWord: word, hasChanged: false }))
|
|
.map(applyRule(rule1))
|
|
.map(applyRule(rule3))
|
|
.map(applyRule(rule4))
|
|
.map(applyRule(rule2))
|
|
.map(({ originalWord }) => originalWord)
|
|
.join(' ')
|
|
}
|