-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
147 lines (113 loc) · 3.16 KB
/
index.js
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
const vowels = /[аеёиоуыэюя]/gi
const deaf = 'длкпстфхцчшщДЛКПСТФХЦЧШЩ'
const signs = ['ь', 'ъ', 'Ь', 'Ъ']
const voiced = ['м', 'р', 'л', 'н', 'М', 'Р', 'Л', 'Н']
const splitLines = source => {
return source.split('\n')
}
const joinLines = lines => {
return lines.join('\n')
}
const splitWords = source => {
return source.split(' ')
}
const joinWords = words => {
return words.join(' ')
}
const addSyllable = (collection, syllable) => {
collection.push(syllable)
}
const indexSign = letters => {
let index = -1
signs.some(letter => {
index = letters.indexOf(letter)
return index !== -1
})
return index
}
const indexYoy = (letters, nextLetter) => {
const index = letters.indexOf('й')
if (index !== -1) {
return index
}
return -1
}
const indexSonoric = (letters) => {
let index = -1
voiced.some(letter => {
index = letters.indexOf(letter)
return index !== -1
})
if (index !== -1) {
const nextLetter = letters[index + 1]
if (deaf.indexOf(nextLetter) === -1) {
return -1
}
}
return index
}
const _syllabifyWord = (word, { separator = '·' } = {}) => {
const collection = []
const vowelsMatches = word.match(vowels)
if (!vowelsMatches) {
return word
}
const letters = word.match(/[a-яё]/gi)
let skip = 0
let currentSyllable = ''
let currentSyllableCount = 0
let isWordEnd = false
let isLastSyllable = false
const len = letters.length
letters.forEach((letter, index) => {
if (skip) {
return skip--
}
currentSyllable += letter
isWordEnd = (index + 1) === len
isLastSyllable = (vowelsMatches.length - collection.length) === 1
if (isLastSyllable) {
return isWordEnd ? addSyllable(collection, currentSyllable) : null
}
if (vowels.test(letter)) {
vowels.lastIndex = 0
currentSyllableCount++
const nextVowel = vowelsMatches[currentSyllableCount]
const nextWovelIndex = letters.indexOf(nextVowel, index + 1)
const between = letters.slice(index + 1, nextWovelIndex)
let indexSlice = -1
indexSlice = indexSign(between)
if (indexSlice === -1) {
indexSlice = indexYoy(between)
}
if (indexSlice === -1) {
indexSlice = indexSonoric(between)
}
if (indexSlice !== -1) {
const sufix = between.slice(0, indexSlice + 1)
currentSyllable += sufix.join('')
skip = sufix.length
}
addSyllable(collection, currentSyllable)
currentSyllable = ''
}
})
return word.replace(/[а-яё]+/i, collection.join(separator))
}
const syllabifyWord = (word, { separator = '·' } = {}) => {
return word
.split('-')
.map(word_ => _syllabifyWord(word_, { separator }))
.join('-')
}
const syllabify = (source, { separator = '·' } = {}) => {
const lines = splitLines(source)
const modifyLines = lines.map(line => {
const words = splitWords(line)
const syllabifyedWords = words.map(word => syllabifyWord(word, { separator }))
return joinWords(syllabifyedWords)
})
return joinLines(modifyLines)
}
module.exports.syllabify = syllabify
module.exports.syllabifyWord = syllabifyWord