""" The 44 Phonemes of English — mapped to simple readable pronunciations. Source: DSF Literacy Resources / Dyslexia Reading Well Each entry maps spelling patterns to their simple phonetic output. We use everyday letter combinations that anyone can read — NOT IPA. The IPA versions are only used in Version 4 (the punchline). This is the core engine. The LLM enhances it. This never fails. """ # Consonant sounds → simple readable spelling # Format: { "spelling_pattern": "simple_sound" } # Ordered longest-first so we match digraphs before single letters CONSONANT_SPELLINGS = { # Digraphs and multi-letter first "tch": "ch", "dge": "j", "ght": "t", "ck": "k", "ph": "f", "gh": "f", # as in laugh (context-dependent, but common) "gn": "n", # as in gnat "kn": "n", # as in knight "pn": "n", # as in pneumonia "ps": "s", # as in psychology "wr": "r", # as in wrong "rh": "r", # as in rhyme "mb": "m", # as in climb (final) "mn": "m", # as in autumn "lm": "m", # as in palm "ng": "ng", "nk": "nk", "qu": "kw", "sh": "sh", "ch": "ch", "th": "th", "wh": "w", "bb": "b", "dd": "d", "ff": "f", "gg": "g", "ll": "l", "mm": "m", "nn": "n", "pp": "p", "rr": "r", "ss": "s", "tt": "t", "zz": "z", # Singles "b": "b", "c": "k", # default, overridden by soft c rule "d": "d", "f": "f", "g": "g", # default, overridden by soft g rule "h": "h", "j": "j", "k": "k", "l": "l", "m": "m", "n": "n", "p": "p", "r": "r", "s": "s", "t": "t", "v": "v", "w": "w", "x": "ks", "y": "y", "z": "z", } # Vowel sounds — short vowels # These are the basic sounds, mapped from common spellings SHORT_VOWELS = { "a": "a", # cat "e": "e", # egg "i": "i", # igloo "o": "o", # orange "u": "u", # mug } # Long vowels — common spelling patterns → simple pronunciation LONG_VOWEL_PATTERNS = { # Long A (say, cake, rain) "ai": "ay", "ay": "ay", "a_e": "ay", # magic e pattern "eigh": "ay", "ey": "ay", "ei": "ay", # Long E (bee, meat, key) "ee": "ee", "ea": "ee", "ie": "ee", # as in brief "ey": "ee", "ei": "ee", # Long I (kite, fly, night) "igh": "eye", "ie": "eye", # as in pie "i_e": "eye", # magic e "y": "eye", # as in fly (end of word) "uy": "eye", # Long O (boat, bone, low) "oa": "oh", "o_e": "oh", # magic e "ow": "oh", # as in low "oe": "oh", "ough": "oh", # as in though # Long U (moon, blue, screw) "oo": "oo", "ew": "oo", "ue": "oo", "u_e": "oo", # magic e "ough": "oo", # as in through } # R-controlled vowels R_CONTROLLED = { "air": "air", "are": "air", "ear": "eer", # as in ear (but also "air" as in pear — context) "eer": "eer", "ere": "eer", "ar": "ar", "or": "or", "ore": "or", "oor": "or", "oar": "or", "our": "or", "ir": "er", "er": "er", "ur": "er", } # Schwa — the lazy vowel, most common sound in English # Almost any vowel letter can make the schwa in unstressed syllables SCHWA_NOTE = "uh" # the 'uh' sound in 'about', 'taken', 'pencil' # Diphthongs DIPHTHONGS = { "oi": "oy", "oy": "oy", "ow": "ow", # as in cow "ou": "ow", # as in shout } # ---- The full simple pronunciation map ---- # This maps the most common English spelling patterns to # how they actually SOUND using everyday letters. # Ordered longest pattern first for greedy matching. PRONUNCIATION_MAP = [ # Multi-letter patterns (check these first) ("tion", "shun"), ("sion", "zhun"), ("ture", "cher"), ("sure", "zher"), ("ous", "us"), ("ight", "yte"), ("ough", "oh"), ("ough", "uff"), ("augh", "awf"), ("ould", "ood"), ("ough", "oo"), ("eigh", "ay"), ("tch", "ch"), ("dge", "j"), ("kn", "n"), ("wr", "r"), ("gn", "n"), ("ph", "f"), ("gh", ""), # often silent: through, night ("ck", "k"), ("ng", "ng"), ("nk", "nk"), ("qu", "kw"), ("sh", "sh"), ("ch", "ch"), ("th", "th"), ("wh", "w"), ("oo", "oo"), ("ee", "ee"), ("ea", "ee"), ("ai", "ay"), ("ay", "ay"), ("oa", "oh"), ("ow", "oh"), ("oi", "oy"), ("oy", "oy"), ("ou", "ow"), ("ew", "oo"), ("ue", "oo"), ("ie", "ee"), ("ar", "ar"), ("or", "or"), ("er", "er"), ("ir", "er"), ("ur", "er"), ] # IPA equivalents — for Version 4 (the unreadable punchline) IPA_MAP = [ ("tion", "\u0283\u0259n"), ("sion", "\u0292\u0259n"), ("ture", "t\u0283\u0259\u0279"), ("ight", "a\u026At"), ("ough", "\u0254\u02D0"), ("eigh", "e\u026A"), ("tch", "t\u0283"), ("dge", "d\u0292"), ("kn", "n"), ("wr", "\u0279"), ("gn", "n"), ("ph", "f"), ("gh", ""), ("ck", "k"), ("ng", "\u014B"), ("nk", "\u014Bk"), ("qu", "kw"), ("sh", "\u0283"), ("ch", "t\u0283"), ("th", "\u03B8"), ("wh", "w"), ("oo", "u\u02D0"), ("ee", "i\u02D0"), ("ea", "i\u02D0"), ("ai", "e\u026A"), ("ay", "e\u026A"), ("oa", "\u0259\u028A"), ("ow", "\u0259\u028A"), ("oi", "\u0254\u026A"), ("oy", "\u0254\u026A"), ("ou", "a\u028A"), ("ew", "ju\u02D0"), ("ue", "u\u02D0"), ("ie", "i\u02D0"), ("ar", "\u0251\u02D0\u0279"), ("or", "\u0254\u02D0\u0279"), ("er", "\u025C\u02D0\u0279"), ("ir", "\u025C\u02D0\u0279"), ("ur", "\u025C\u02D0\u0279"), ("a", "\u00E6"), ("e", "\u025B"), ("i", "\u026A"), ("o", "\u0252"), ("u", "\u028C"), ("b", "b"), ("c", "k"), ("d", "d"), ("f", "f"), ("g", "\u0261"), ("h", "h"), ("j", "d\u0292"), ("k", "k"), ("l", "l"), ("m", "m"), ("n", "n"), ("p", "p"), ("r", "\u0279"), ("s", "s"), ("t", "t"), ("v", "v"), ("w", "w"), ("x", "ks"), ("y", "j"), ("z", "z"), ] def word_to_ipa(word): """Convert a word to IPA-like transcription (deliberately unreadable).""" result = "" w = word.lower() i = 0 while i < len(w): matched = False # Try longest patterns first for pattern, ipa in IPA_MAP: plen = len(pattern) if w[i:i+plen] == pattern: result += ipa i += plen matched = True break if not matched: result += w[i] i += 1 return result def text_to_ipa(text): """Convert full text to IPA transcription.""" import re words = text.split() ipa_words = [] for word in words: # Preserve punctuation prefix = "" suffix = "" core = word while core and not core[0].isalnum(): prefix += core[0] core = core[1:] while core and not core[-1].isalnum(): suffix = core[-1] + suffix core = core[:-1] if core: ipa_words.append(f"{prefix}{word_to_ipa(core)}{suffix}") else: ipa_words.append(word) return "/\u200B" + " ".join(ipa_words) + "\u200B/"