| """ |
| 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_SPELLINGS = { |
| |
| "tch": "ch", |
| "dge": "j", |
| "ght": "t", |
| "ck": "k", |
| "ph": "f", |
| "gh": "f", |
| "gn": "n", |
| "kn": "n", |
| "pn": "n", |
| "ps": "s", |
| "wr": "r", |
| "rh": "r", |
| "mb": "m", |
| "mn": "m", |
| "lm": "m", |
| "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", |
| |
| "b": "b", |
| "c": "k", |
| "d": "d", |
| "f": "f", |
| "g": "g", |
| "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", |
| } |
|
|
| |
| |
| SHORT_VOWELS = { |
| "a": "a", |
| "e": "e", |
| "i": "i", |
| "o": "o", |
| "u": "u", |
| } |
|
|
| |
| LONG_VOWEL_PATTERNS = { |
| |
| "ai": "ay", |
| "ay": "ay", |
| "a_e": "ay", |
| "eigh": "ay", |
| "ey": "ay", |
| "ei": "ay", |
|
|
| |
| "ee": "ee", |
| "ea": "ee", |
| "ie": "ee", |
| "ey": "ee", |
| "ei": "ee", |
|
|
| |
| "igh": "eye", |
| "ie": "eye", |
| "i_e": "eye", |
| "y": "eye", |
| "uy": "eye", |
|
|
| |
| "oa": "oh", |
| "o_e": "oh", |
| "ow": "oh", |
| "oe": "oh", |
| "ough": "oh", |
|
|
| |
| "oo": "oo", |
| "ew": "oo", |
| "ue": "oo", |
| "u_e": "oo", |
| "ough": "oo", |
| } |
|
|
| |
| R_CONTROLLED = { |
| "air": "air", |
| "are": "air", |
| "ear": "eer", |
| "eer": "eer", |
| "ere": "eer", |
| "ar": "ar", |
| "or": "or", |
| "ore": "or", |
| "oor": "or", |
| "oar": "or", |
| "our": "or", |
| "ir": "er", |
| "er": "er", |
| "ur": "er", |
| } |
|
|
| |
| |
| SCHWA_NOTE = "uh" |
|
|
| |
| DIPHTHONGS = { |
| "oi": "oy", |
| "oy": "oy", |
| "ow": "ow", |
| "ou": "ow", |
| } |
|
|
| |
| |
| |
| |
|
|
| PRONUNCIATION_MAP = [ |
| |
| ("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", ""), |
| ("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_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 |
| |
| 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: |
| |
| 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/" |
|
|