Skip to content

Commit

Permalink
fix: fleeting vowel inference
Browse files Browse the repository at this point in the history
  • Loading branch information
noomorph committed Jan 10, 2024
1 parent 522d43f commit 172423a
Show file tree
Hide file tree
Showing 10 changed files with 317 additions and 286 deletions.
41 changes: 41 additions & 0 deletions src/common/fluentVowels.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { inferFluentVowel, markFluentVowel } from './fluentVowels';

describe('fluentVowels', () => {
describe('markFluentVowel', () => {
it('marks the fluent vowel in the word', () => {
expect(markFluentVowel('pes', 'psa')).toBe('p(e)s');
expect(markFluentVowel('son', 'sna')).toBe('s(o)n');
});

it('returns the same word when there is no fluent vowel', () => {
expect(markFluentVowel('mama', 'mama')).toBe('mama');
});

it('marks the fluent vowel when it includes a diacritic', () => {
expect(markFluentVowel('pènj', 'pnja')).toBe('p(e)nj');
expect(markFluentVowel('sòn', 'sna')).toBe('s(o)n');
});
});

describe('inferFluentVowel', () => {
it('infers the fluent vowel in the word', () => {
expect(inferFluentVowel('pės')).toBe('p(e)s');
expect(inferFluentVowel('pèsȯk')).toBe('pès(o)k');
expect(inferFluentVowel('sȯn')).toBe('s(o)n');
expect(inferFluentVowel('dėnj')).toBe('d(e)nj');
expect(inferFluentVowel('orėl')).toBe('or(e)l');
});

it('infers the fluent vowel in complex words', () => {
expect(inferFluentVowel('pėsȯk, kotȯk i orėl')).toBe(
'pės(o)k, kot(o)k i or(e)l',
);
});

it('does not infer incorrect fluent vowels in the word', () => {
expect(inferFluentVowel('pėj')).toBe('pėj');
expect(inferFluentVowel('dvėri')).toBe('dvėri');
expect(inferFluentVowel('dȯžď')).toBe('dȯžď');
});
});
});
59 changes: 59 additions & 0 deletions src/common/fluentVowels.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { ALL_CHARACTERS, CONSONANT_CHARACTERS } from '../constants';

const LETTERS = new Set(ALL_CHARACTERS);
const CONSONANTS = new Set(CONSONANT_CHARACTERS);

export function markFluentVowel(word: string, add: string): string {
let i = 0;

const L = Math.min(word.length - 1, add.length);
while (i < L && word[i] === add[i]) {
i++;
}

if (word[i] !== add[i] && word[i + 1] === add[i]) {
return replaceFluentVowel(word, i);
}

return word;
}

export function inferFluentVowel(word: string): string {
let i = word.length - 1;
let end = word.length;
let replaced = false;
let result = word;

while (i > 0) {
const char = word[i];
if (!LETTERS.has(char)) {
end = i;
replaced = false;
}

if (!replaced && isFleetingVowel(char)) {
if (isLastSyllable(word, i, end)) {
result = replaceFluentVowel(result, i);
}
}

i--;
}

return result;
}

function isFleetingVowel(char: string): boolean {
return char === 'è' || char === 'ė' || char === 'ȯ' || char === 'ò';
}

function replaceFluentVowel(word: string, j: number): string {
const fluentVowel = word[j].normalize('NFD')[0];
return `${word.slice(0, j)}(${fluentVowel})${word.slice(j + 1)}`;
}

function isLastSyllable(word: string, i: number, end: number): boolean {
if (i === end - 2) return CONSONANTS.has(word[i + 1]);
if (i === end - 3) return word[i + 1] === 'n' && word[i + 2] === 'j';
return false;
}
2 changes: 1 addition & 1 deletion src/common/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from './stripDiacritics';
export * from './markFluentVowel';
export * from './fluentVowels';
17 changes: 0 additions & 17 deletions src/common/markFluentVowel.test.ts

This file was deleted.

19 changes: 0 additions & 19 deletions src/common/markFluentVowel.ts

This file was deleted.

7 changes: 7 additions & 0 deletions src/constants/alphabet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const ALL_CHARACTERS =
'aáàăâåąāæbcćçčdďđḓeéèĕêěëėęēǝfghiíìĭîīıjĵklĺľļłŀljmnńňñņnjoóòŏôöȯǫœpqrŕṙřsśšŠtťṱuúùŭûůũųūvwxyýzźżž'.split(
'',
);

export const CONSONANT_CHARACTERS =
'bcćçčdďđḓfghklĺľļłŀljmnńňñņnjpqrŕṙřsśštťṱvwxzźżž'.split('');
1 change: 1 addition & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './alphabet';
export * from './bcp47';
export * from './glagolitic';
Loading

0 comments on commit 172423a

Please sign in to comment.