UNPKG

@unglish/word-generator

Version:

A simple generator for creating unglish words.

88 lines (87 loc) 3.9 kB
import getWeightedOption from "../utils/getWeightedOption"; /** * Converts a syllable object into a string representation of its pronunciation. * * @param syllable - The Syllable object to be pronounced. * @returns A string representing the pronunciation of the syllable. * * This function takes a Syllable object and converts it into a string * representation of its pronunciation. It does this by concatenating * the phonetic sounds of each phoneme in the onset, nucleus, and coda * of the syllable. * * The function uses a helper function `reducePhonemes` to concatenate * the sounds of phonemes in each part of the syllable. */ const pronounceSyllable = (position, context) => { const syllable = context.word.syllables[position]; const onset = syllable.onset.map((phoneme) => phoneme.sound).join(''); const nucleus = syllable.nucleus.map((phoneme) => phoneme.sound).join(''); const coda = syllable.coda.map((phoneme) => phoneme.sound).join(''); return `${onset}${nucleus}${coda}`; }; /** * Determines if a syllable should be stressed based on its position and word context. * * @param position - The position of the syllable within the word (0-based index). * @param context - The context of the word being generated, including syllable count and word structure. * @returns A boolean value indicating whether the syllable should be stressed. */ const shouldStressSyllable = (position, context) => { const { word, syllableCount } = context; // Monosyllabic words are always stressed - but we do not demarkate it if (syllableCount === 1) return true; // Two-syllable words if (syllableCount === 2) { const stressFirst = getWeightedOption([[true, 70], [false, 30]]); return stressFirst ? position === 0 : position === 1; } // Three-syllable words if (syllableCount === 3) { const stressPosition = getWeightedOption([[0, 60], [1, 30], [2, 10]]); return position === stressPosition; } // Words with four or more syllables if (syllableCount >= 4) { const lastSyllable = word.syllables[syllableCount - 1]; if (lastSyllable.nucleus.some(phoneme => ['ɪ', 'ə'].includes(phoneme.sound))) { // Suffixes like -ic, -ity, -ion often cause stress on the penultimate syllable return position === syllableCount - 2; } // For longer words, distribute stress more evenly const stressPosition = getWeightedOption([ [0, 40], [1, 30], [syllableCount - 2, 20], [syllableCount - 3, 10] ]); return position === stressPosition; } // Default to stressing the first syllable if no other rules apply return position === 0; }; /** * Converts an array of syllables into a string representation of the word's pronunciation. * * @param syllables - An array of Syllable objects representing the word. * @returns A string representing the pronunciation of the entire word. * * This function iterates through each syllable in the given array, * pronounces each syllable using the `pronounceSyllable` function, * and concatenates the results to form a complete pronunciation guide * for the entire word. * * The resulting string contains the phonetic representation of the word, * with each syllable's sounds joined together without any separators. */ export const generatePronunciation = (context) => { const syllables = context.word.syllables; const pronunciationParts = new Array(syllables.length); for (let i = 0; i < syllables.length; i++) { const isStressed = shouldStressSyllable(i, context); const syllablePronunciation = pronounceSyllable(i, context); pronunciationParts.push(i > 0 ? isStressed ? `'` : `.` : '', syllablePronunciation); } context.word.pronunciation = pronunciationParts.join(''); };