UNPKG

phonemize

Version:

Fast phonemizer with rule-based G2P prediction. Pure JavaScript implementation.

106 lines (105 loc) 4.69 kB
/** * English suffix table (P2.0 of G2P redesign). * * Each entry describes one productive English suffix: its orthography, * its IPA realization, its stress-shift class, and whether it triggers * vowel reduction in the base. The decomposer uses this to peel a word * down to its base, the stress FSM uses the class to re-place stress, * and the reduction rules use the trigger flag to decide whether * unstressed base vowels collapse. * * Stress classes follow Chomsky-Halle / Hayes: * - "neutral": base stress preserved; suffix unstressed. * Germanic suffixes: -ness, -less, -ly, -ed, -ing, … * - "pre": stress on syllable immediately before suffix. * Latinate Class-I suffixes: -ity, -tion, -ic, -ial, … * - "pre2": stress on syllable two before suffix. * -ative, -atory, -ical (in some cases) * - "self": suffix bears primary stress. * -ee, -eer, -ese, -ette, -oon, -aire * * The reduction flag defaults from class: pre/pre2/self reduce, neutral * does not. Override only for known irregulars. * * Order in SUFFIXES matters only for the decomposer's longest-match * heuristic; the table is indexed by length at module load. */ /** * Stress class — positional, measured from the end of the word: * * - "neutral": inherit base stress (suffix doesn't alter it). * Germanic Class-II suffixes: -ness, -less, -ly, -ed, -ing, … * - "penult": primary stress on penultimate syllable of the whole word. * Class-I: -ation, -ition, -ic, -ous, -al, -ant/-ent, * -ization, -tion, -sion, -ial. * - "antepenult": primary stress on antepenultimate (3rd-from-end). * Class-I: -ity, -ical, -ative, -ology, -ability, -ological. * - "final": primary stress on the last syllable. * Self-stressing: -ee, -eer, -ese, -ette, -oon, -aire. * * This single positional view replaces the older "pre/pre2/first/self" * vocabulary, which was relative to the suffix's start position and turned * out to overlap depending on suffix syllable count. Position-from-end is * both simpler and matches the underlying Latin penult/antepenult rule. */ export type StressClass = "neutral" | "penult" | "antepenult" | "final"; export interface SuffixEntry { /** Orthographic suffix matched at word end. */ suffix: string; /** Phoneme realization (no stress marks; stress comes from class). */ ipa: string; /** Stress-shift class. */ stress: StressClass; /** Whether the base undergoes vowel reduction; default by class. */ reduces?: boolean; /** Minimum base length required after stripping; guards over-stripping. */ minBase?: number; /** Base recovery: undo orthographic mutation. e.g. -iness ← -y + -ness. */ recover?: { strip: string; add: string; }; /** Optional alternative base spellings to also try (e.g., "abat" → "abate"). */ baseAlts?: string[]; /** Optional context guard: regex matched against the base after stripping. */ baseGuard?: RegExp; /** Phoneme-level allomorphs that may also realize this suffix. Caller * picks the one matching the actual IPA tail. Used for -s/-ed allomorphy. */ ipaAlts?: string[]; } export declare const SUFFIXES: SuffixEntry[]; /** * Find the longest suffix entry matching the end of `word`. Returns the * primary base (after any orthographic recovery) plus a list of alternative * base spellings to try (e.g., for -ed/-ing also try base+"e", since * abated→abate dropped the final e). Caller can pick which alternative * resolves against a dictionary. * * Returns null if no entry matches under its minBase / baseGuard constraints. */ export declare function matchSuffix(word: string): { entry: SuffixEntry; base: string; baseAlts: string[]; } | null; /** * Strip suffixes iteratively until no more match. Returns the chain of * (entry, intermediate base) and the final base. */ export interface DecompositionStep { entry: SuffixEntry; /** Word/base before this suffix is stripped. */ before: string; /** Resulting base after stripping (input to the next iteration). */ after: string; /** Alternative base spellings (e-drop / consonant doubling recovery). */ afterAlts: string[]; } export interface Decomposition { base: string; baseAlts: string[]; steps: DecompositionStep[]; } export declare function decompose(word: string, maxDepth?: number): Decomposition; /** Default reduction trigger by class. */ export declare function reduces(entry: SuffixEntry): boolean;