diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/language.test.ts | 70 | ||||
| -rw-r--r-- | src/language.ts | 99 | 
2 files changed, 134 insertions, 35 deletions
| diff --git a/src/language.test.ts b/src/language.test.ts index d3c6f23..62b03a2 100644 --- a/src/language.test.ts +++ b/src/language.test.ts @@ -69,3 +69,73 @@ test('fail to output impossible consonants', () => {  		voice: false,  	})).toBe('');  }); + + +test('all consonants can be selected', () => { +	expect(lang.pickConsonants( +		[ lang.ConsonantPlace.Bilabial ], +		[ lang.ConsonantManner.Nasal ], +		[ true, true ], +	)).toEqual([ +		{ +			place: lang.ConsonantPlace.Bilabial, +			manner: lang.ConsonantManner.Nasal, +			voice: false, +		}, +		{ +			place: lang.ConsonantPlace.Bilabial, +			manner: lang.ConsonantManner.Nasal, +			voice: true, +		}, +	]); + +	expect(lang.pickConsonants( +		[ lang.ConsonantPlace.Labiodental ], +		[  +			lang.ConsonantManner.Nasal, +			lang.ConsonantManner.Plosive, +			lang.ConsonantManner.SibilantAffricate, +			lang.ConsonantManner.NonSibilantAffricate, +			lang.ConsonantManner.SibilantFricative, +			lang.ConsonantManner.NonSibilantFricative, +			lang.ConsonantManner.Approximant, +			lang.ConsonantManner.Tap, +			lang.ConsonantManner.Trill, +			lang.ConsonantManner.LateralAffricate, +			lang.ConsonantManner.LateralFricative, +			lang.ConsonantManner.LateralApproximant, +			lang.ConsonantManner.LateralTap, +		], +		[ true, false ], +	)).toEqual([ +		{ +			place: lang.ConsonantPlace.Labiodental, +			manner: lang.ConsonantManner.Nasal, +			voice: false, +		}, +		{ +			place: lang.ConsonantPlace.Labiodental, +			manner: lang.ConsonantManner.Plosive, +			voice: false, +		}, +		{ +			place: lang.ConsonantPlace.Labiodental, +			manner: lang.ConsonantManner.NonSibilantAffricate, +			voice: false, +		}, +		{ +			place: lang.ConsonantPlace.Labiodental, +			manner: lang.ConsonantManner.NonSibilantFricative, +			voice: false, +		}, +	]); + + +	expect(lang.pickConsonants( +		[ lang.ConsonantPlace.Bilabial, lang.ConsonantPlace.Alveolar ], +		[ lang.ConsonantManner.Plosive, lang.ConsonantManner.Tap ], +		[ true, true ], +	).map(lang.consonantFeaturesToIpa)).toEqual([ +		'p', 'b', 'ⱱ̟', 't', 'd', 'ɾ̥', 'ɾ', +	]); +}); diff --git a/src/language.ts b/src/language.ts index 0721e09..c0360b8 100644 --- a/src/language.ts +++ b/src/language.ts @@ -1,16 +1,16 @@  export enum VowelHeight { -	Open, -	NearOpen, -	OpenMid, -	Mid, -	CloseMid, -	NearClose, -	Close, +	Open = 'open', +	NearOpen = 'nearOpen', +	OpenMid = 'openMid', +	Mid = 'mid', +	CloseMid = 'closeMid', +	NearClose = 'nearClose', +	Close = 'close',  }  export enum VowelDepth { -	Front, -	Central, -	Back, +	Front = 'front', +	Central = 'central', +	Back = 'back',  }  export interface VowelFeatures {  	height: VowelHeight; @@ -106,33 +106,33 @@ export function vowelFeaturesToIpa(features: VowelFeatures): string {  export enum ConsonantPlace { -	Bilabial, -	Labiodental, -	Linguolabial, -	Dental, -	Alveolar, -	Postalveolar, -	Retroflex, -	Palatal, -	Velar, -	Uvular, -	Pharyngeal, -	Glottal, +	Bilabial = 'bilabial', +	Labiodental = 'labiodental', +	Linguolabial = 'labiolingual', +	Dental = 'dental', +	Alveolar = 'alveolar', +	Postalveolar = 'postalveolar', +	Retroflex = 'retroflex', +	Palatal = 'palatal', +	Velar = 'velar', +	Uvular = 'uvular', +	Pharyngeal = 'pharyngeal', +	Glottal = 'glottal',  }  export enum ConsonantManner { -	Nasal, -	Plosive, -	SibilantAffricate, -	NonSibilantAffricate, -	SibilantFricative, -	NonSibilantFricative, -	Approximant, -	Tap, -	Trill, -	LateralAffricate, -	LateralFricative, -	LateralApproximant, -	LateralTap, +	Nasal = 'nasal', +	Plosive = 'plosive', +	SibilantAffricate = 'sibilantAffricate', +	NonSibilantAffricate = 'nonSibilantAffricate', +	SibilantFricative = 'sibilantFricative', +	NonSibilantFricative = 'nonSibilantFricative', +	Approximant = 'approximant', +	Tap = 'tap', +	Trill = 'trill', +	LateralAffricate = 'lateralAffricate', +	LateralFricative = 'lateralFricative', +	LateralApproximant = 'lateralApproximant', +	LateralTap = 'lateralTap',  }  export interface ConsonantFeatures {  	place: ConsonantPlace; @@ -480,3 +480,32 @@ export function consonantFeaturesToIpa(features: ConsonantFeatures): string {  		}  	}  } + + +export function isConsonantPossible(features: ConsonantFeatures): boolean { +	return consonantFeaturesToIpa(features) !== ''; +} + + +// get all of the consonants based on the features selected +export function pickConsonants( +	places: ConsonantPlace[], +	manners: ConsonantManner[], +	voicing: [boolean, boolean], +): ConsonantFeatures[] { +	return places.map<ConsonantFeatures[]>( +		place => manners.map<ConsonantFeatures[]>( +			manner => { +				const [ unvoiced, voiced ] = voicing; +				const result = []; +				if (unvoiced) { +					result.push({ place, manner, voice: false }); +				} +				if (voiced) { +					result.push({ place, manner, voice: true }); +				} +				return result; +			} +		).flat() +	).flat().filter(isConsonantPossible); +} | 
