Skip to content

Commit 8503b88

Browse files
committed
toLowerCaseRu
1 parent 4fe1c99 commit 8503b88

1 file changed

Lines changed: 33 additions & 9 deletions

File tree

js/RussianNouns.js

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,30 @@
5959
"COMMON": GenderValues[3]
6060
});
6161

62+
function toLowerCaseRu(s) {
63+
// Это на самом деле быстрее, чем нативный toLowerCase, во всяком случае в Chrome,
64+
// поскольку нативный toLowerCase преобразует все алфавиты, а здесь только кириллица.
65+
66+
let codes = new Array(s.length);
67+
68+
for (let i = 0; i < s.length; i++) {
69+
let ch = s.charCodeAt(i);
70+
71+
if ((ch >= 0x0410) && (ch <= 0x042F)) {
72+
ch += 0x20;
73+
} else if ((ch >= 0x0400) && (ch <= 0x040F)) {
74+
ch += 0x50;
75+
}
76+
77+
codes[i] = ch;
78+
}
79+
80+
// Функция apply может вызвать RangeError при очень длинных
81+
// массивах (лимит аргументов), но для слов — это не проблема.
82+
83+
return String.fromCharCode.apply(null, codes);
84+
}
85+
6286
/**
6387
* @param o A plain old JavaScript object.
6488
* @returns {string|null} Описание ошибки на английском или null.
@@ -312,7 +336,7 @@
312336
const vowels = 0b11101000000010000100000100100001;
313337

314338
function isVowel(ch) {
315-
return bincludes(vowels, ch.toLowerCase());
339+
return bincludes(vowels, toLowerCaseRu(ch));
316340
}
317341

318342
function isConsonantLc(lcChar) {
@@ -1592,7 +1616,7 @@
15921616
head = 'полу' + head.substring(3);
15931617
}
15941618

1595-
let lcStem = stem.toLowerCase();
1619+
let lcStem = toLowerCaseRu(stem);
15961620

15971621
const soft = () => (half && lcWord.endsWith('я')) || softD1(lcWord);
15981622

@@ -1874,7 +1898,7 @@
18741898
const lcWord = lemma.lower();
18751899

18761900
const stem = getNounStem(lemma, lcWord);
1877-
const lcStem = stem.toLowerCase();
1901+
const lcStem = toLowerCaseRu(stem);
18781902

18791903
const head = init(word);
18801904
const lcHead = init(lcWord);
@@ -2302,7 +2326,7 @@
23022326
Object.freeze(stressedEnding);
23032327

23042328
const stem = getNounStem(lemma, lcWord, stressedEnding[0]);
2305-
const lcStem = stem.toLowerCase();
2329+
const lcStem = toLowerCaseRu(stem);
23062330

23072331
if (lcWord.endsWith('яя')) {
23082332
result.push(nInit(word, 2) + 'ие');
@@ -2335,7 +2359,7 @@
23352359

23362360
function softPatronymicForm2() {
23372361
const part = simpleFirstPart;
2338-
const index = part.toLowerCase().indexOf('ье');
2362+
const index = toLowerCaseRu(part).indexOf('ье');
23392363
const r = upperLike('и', part[index]);
23402364
return part.substring(0, index) + r + part.substring(index + 1);
23412365
}
@@ -2806,7 +2830,7 @@
28062830
// молодцы
28072831

28082832
function declinePlural(engine, lemma, grCase, plural) {
2809-
const lcPlural = plural.toLowerCase();
2833+
const lcPlural = toLowerCaseRu(plural);
28102834

28112835
const lcLastChar = last(lcPlural);
28122836
const lcLastBit = lcBit(lcLastChar);
@@ -2874,7 +2898,7 @@
28742898
const declension = lemma.getDeclension();
28752899

28762900
const genitiveStem = () => {
2877-
const lcStem = stem.toLowerCase();
2901+
const lcStem = toLowerCaseRu(stem);
28782902

28792903
const dependsOnStress = ['жки', 'шки', 'чки', 'ножны'];
28802904

@@ -3081,13 +3105,13 @@
30813105
}
30823106
}
30833107

3084-
if (stem.toLowerCase().endsWith('ийк')) {
3108+
if (toLowerCaseRu(stem).endsWith('ийк')) {
30853109
return nInit(stem, 2) + 'ек';
30863110
}
30873111

30883112
if ((stem.length === lcPlural.length - 1) && endsWithLeaf(lcPlural, declinePluralSoftEndings)) {
30893113

3090-
if ('ьй'.includes(lastOfNInitial(stem, 1).toLowerCase()) && !lemma.isAnimate()) {
3114+
if ('ьй'.includes(toLowerCaseRu(lastOfNInitial(stem, 1))) && !lemma.isAnimate()) {
30913115
const end = last(stem);
30923116
return nInit(stem, 2) + upperLike('е', end) + end;
30933117
} else if (endsWithAny(lcPlural, ['земли', 'петли', 'пли', 'вли'])) {

0 commit comments

Comments
 (0)