ipa-chart-explorerer / ipa_data.py
profplate's picture
Create ipa_data.py
739b228 verified
"""
IPA Data Module — Shared phoneme data for all IPA Hugging Face Spaces.
Contains:
- Full IPA consonant inventory with articulatory features
- Full IPA vowel inventory with height/backness/rounding
- Spanish phoneme annotations and example words
- Chart layout constants (place/manner ordering, vowel trapezoid coordinates)
"""
# =============================================================================
# CONSONANT CHART DATA
# =============================================================================
# Column order for the consonant chart (place of articulation)
CONSONANT_PLACES = [
"bilabial",
"labiodental",
"dental",
"alveolar",
"postalveolar",
"retroflex",
"palatal",
"velar",
"uvular",
"pharyngeal",
"glottal",
]
# Row order for the consonant chart (manner of articulation)
CONSONANT_MANNERS = [
"plosive",
"nasal",
"trill",
"tap/flap",
"fricative",
"lateral fricative",
"approximant",
"lateral approximant",
]
# Full IPA consonant data
# Each entry: symbol -> {place, manner, voicing, name, spanish, spanish_example, espeak_code, languages}
CONSONANTS = {
# === PLOSIVES ===
"p": {
"place": "bilabial", "manner": "plosive", "voicing": "voiceless",
"name": "voiceless bilabial plosive",
"spanish": True, "spanish_example": "padre",
"espeak_code": "p",
"languages": ["English", "Spanish", "French", "German", "Mandarin"],
},
"b": {
"place": "bilabial", "manner": "plosive", "voicing": "voiced",
"name": "voiced bilabial plosive",
"spanish": True, "spanish_example": "boca",
"espeak_code": "b",
"languages": ["English", "Spanish", "French", "Arabic"],
},
"t": {
"place": "alveolar", "manner": "plosive", "voicing": "voiceless",
"name": "voiceless alveolar plosive",
"spanish": True, "spanish_example": "taza",
"espeak_code": "t",
"languages": ["English", "Spanish", "French", "German"],
},
"d": {
"place": "alveolar", "manner": "plosive", "voicing": "voiced",
"name": "voiced alveolar plosive",
"spanish": True, "spanish_example": "dedo",
"espeak_code": "d",
"languages": ["English", "Spanish", "French", "Italian"],
},
"t\u0288": { # ʈ
"place": "retroflex", "manner": "plosive", "voicing": "voiceless",
"name": "voiceless retroflex plosive",
"spanish": False, "spanish_example": None,
"espeak_code": "t.",
"languages": ["Hindi", "Swedish", "Norwegian"],
},
"\u0256": { # ɖ
"place": "retroflex", "manner": "plosive", "voicing": "voiced",
"name": "voiced retroflex plosive",
"spanish": False, "spanish_example": None,
"espeak_code": "d.",
"languages": ["Hindi", "Tamil", "Swedish"],
},
"c": {
"place": "palatal", "manner": "plosive", "voicing": "voiceless",
"name": "voiceless palatal plosive",
"spanish": False, "spanish_example": None,
"espeak_code": "c",
"languages": ["Hungarian", "Turkish", "Greek"],
},
"\u025f": { # ɟ
"place": "palatal", "manner": "plosive", "voicing": "voiced",
"name": "voiced palatal plosive",
"spanish": False, "spanish_example": None,
"espeak_code": "J",
"languages": ["Hungarian", "Turkish", "Latvian"],
},
"k": {
"place": "velar", "manner": "plosive", "voicing": "voiceless",
"name": "voiceless velar plosive",
"spanish": True, "spanish_example": "casa",
"espeak_code": "k",
"languages": ["English", "Spanish", "French", "German", "Mandarin"],
},
"\u0261": { # ɡ
"place": "velar", "manner": "plosive", "voicing": "voiced",
"name": "voiced velar plosive",
"spanish": True, "spanish_example": "gato",
"espeak_code": "g",
"languages": ["English", "Spanish", "French", "German"],
},
"q": {
"place": "uvular", "manner": "plosive", "voicing": "voiceless",
"name": "voiceless uvular plosive",
"spanish": False, "spanish_example": None,
"espeak_code": "q",
"languages": ["Arabic", "Quechua", "Inuktitut"],
},
"\u0262": { # ɢ
"place": "uvular", "manner": "plosive", "voicing": "voiced",
"name": "voiced uvular plosive",
"spanish": False, "spanish_example": None,
"espeak_code": None,
"languages": ["Somali", "Inuktitut"],
},
"\u0294": { # ʔ
"place": "glottal", "manner": "plosive", "voicing": "voiceless",
"name": "glottal stop",
"spanish": False, "spanish_example": None,
"espeak_code": "?",
"languages": ["English (uh-oh)", "Arabic", "Hawaiian", "German"],
},
# === NASALS ===
"m": {
"place": "bilabial", "manner": "nasal", "voicing": "voiced",
"name": "voiced bilabial nasal",
"spanish": True, "spanish_example": "madre",
"espeak_code": "m",
"languages": ["English", "Spanish", "French", "German", "Mandarin"],
},
"\u0271": { # ɱ
"place": "labiodental", "manner": "nasal", "voicing": "voiced",
"name": "voiced labiodental nasal",
"spanish": False, "spanish_example": None,
"espeak_code": "M",
"languages": ["English (comfort)", "Italian", "Dutch"],
},
"n": {
"place": "alveolar", "manner": "nasal", "voicing": "voiced",
"name": "voiced alveolar nasal",
"spanish": True, "spanish_example": "noche",
"espeak_code": "n",
"languages": ["English", "Spanish", "French", "German", "Mandarin"],
},
"\u0273": { # ɳ
"place": "retroflex", "manner": "nasal", "voicing": "voiced",
"name": "voiced retroflex nasal",
"spanish": False, "spanish_example": None,
"espeak_code": "n.",
"languages": ["Hindi", "Swedish", "Norwegian"],
},
"\u0272": { # ɲ
"place": "palatal", "manner": "nasal", "voicing": "voiced",
"name": "voiced palatal nasal",
"spanish": True, "spanish_example": "niño (ñ)",
"espeak_code": "n^",
"languages": ["Spanish", "French (cognac)", "Italian", "Portuguese"],
},
"\u014b": { # ŋ
"place": "velar", "manner": "nasal", "voicing": "voiced",
"name": "voiced velar nasal",
"spanish": True, "spanish_example": "tengo (before g/k)",
"espeak_code": "N",
"languages": ["English (sing)", "Spanish", "German", "Mandarin"],
},
"\u0274": { # ɴ
"place": "uvular", "manner": "nasal", "voicing": "voiced",
"name": "voiced uvular nasal",
"spanish": False, "spanish_example": None,
"espeak_code": None,
"languages": ["Japanese", "Inuktitut"],
},
# === TRILLS ===
"\u0299": { # ʙ
"place": "bilabial", "manner": "trill", "voicing": "voiced",
"name": "voiced bilabial trill",
"spanish": False, "spanish_example": None,
"espeak_code": None,
"languages": ["Nias", "Titan"],
},
"r": {
"place": "alveolar", "manner": "trill", "voicing": "voiced",
"name": "voiced alveolar trill",
"spanish": True, "spanish_example": "perro",
"espeak_code": "r",
"languages": ["Spanish", "Italian", "Russian", "Arabic"],
},
"\u0280": { # ʀ
"place": "uvular", "manner": "trill", "voicing": "voiced",
"name": "voiced uvular trill",
"spanish": False, "spanish_example": None,
"espeak_code": "R",
"languages": ["French", "German", "Dutch"],
},
# === TAPS / FLAPS ===
"\u2c71": { # ⱱ
"place": "labiodental", "manner": "tap/flap", "voicing": "voiced",
"name": "voiced labiodental flap",
"spanish": False, "spanish_example": None,
"espeak_code": None,
"languages": ["Mono", "some Central African languages"],
},
"\u027e": { # ɾ
"place": "alveolar", "manner": "tap/flap", "voicing": "voiced",
"name": "voiced alveolar tap",
"spanish": True, "spanish_example": "pero",
"espeak_code": "*",
"languages": ["Spanish", "Japanese", "Korean", "Portuguese"],
},
"\u027d": { # ɽ
"place": "retroflex", "manner": "tap/flap", "voicing": "voiced",
"name": "voiced retroflex flap",
"spanish": False, "spanish_example": None,
"espeak_code": "*.",
"languages": ["Hindi", "Urdu", "Hausa"],
},
# === FRICATIVES ===
"\u0278": { # ɸ
"place": "bilabial", "manner": "fricative", "voicing": "voiceless",
"name": "voiceless bilabial fricative",
"spanish": False, "spanish_example": None,
"espeak_code": "F",
"languages": ["Japanese (fu)", "Ewe"],
},
"\u03b2": { # β
"place": "bilabial", "manner": "fricative", "voicing": "voiced",
"name": "voiced bilabial fricative",
"spanish": True, "spanish_example": "lobo (allophone of /b/)",
"espeak_code": "B",
"languages": ["Spanish (allophone)", "Ewe", "Japanese"],
},
"f": {
"place": "labiodental", "manner": "fricative", "voicing": "voiceless",
"name": "voiceless labiodental fricative",
"spanish": True, "spanish_example": "fuego",
"espeak_code": "f",
"languages": ["English", "Spanish", "French", "German"],
},
"v": {
"place": "labiodental", "manner": "fricative", "voicing": "voiced",
"name": "voiced labiodental fricative",
"spanish": False, "spanish_example": None,
"espeak_code": "v",
"languages": ["English", "French", "German", "Russian"],
},
"\u03b8": { # θ
"place": "dental", "manner": "fricative", "voicing": "voiceless",
"name": "voiceless dental fricative",
"spanish": True, "spanish_example": "zapato (Castilian)",
"espeak_code": "T",
"languages": ["English (think)", "Spanish (Castilian)", "Greek"],
},
"\u00f0": { # ð
"place": "dental", "manner": "fricative", "voicing": "voiced",
"name": "voiced dental fricative",
"spanish": True, "spanish_example": "dedo (allophone of /d/)",
"espeak_code": "D",
"languages": ["English (the)", "Spanish (allophone)", "Icelandic"],
},
"s": {
"place": "alveolar", "manner": "fricative", "voicing": "voiceless",
"name": "voiceless alveolar fricative",
"spanish": True, "spanish_example": "sol",
"espeak_code": "s",
"languages": ["English", "Spanish", "French", "German", "Mandarin"],
},
"z": {
"place": "alveolar", "manner": "fricative", "voicing": "voiced",
"name": "voiced alveolar fricative",
"spanish": False, "spanish_example": None,
"espeak_code": "z",
"languages": ["English", "French", "Italian", "Russian"],
},
"\u0283": { # ʃ
"place": "postalveolar", "manner": "fricative", "voicing": "voiceless",
"name": "voiceless postalveolar fricative",
"spanish": False, "spanish_example": None,
"espeak_code": "S",
"languages": ["English (ship)", "French (chat)", "German (schön)"],
},
"\u0292": { # ʒ
"place": "postalveolar", "manner": "fricative", "voicing": "voiced",
"name": "voiced postalveolar fricative",
"spanish": False, "spanish_example": None,
"espeak_code": "Z",
"languages": ["English (measure)", "French (je)", "Portuguese"],
},
"\u0282": { # ʂ
"place": "retroflex", "manner": "fricative", "voicing": "voiceless",
"name": "voiceless retroflex fricative",
"spanish": False, "spanish_example": None,
"espeak_code": "s.",
"languages": ["Mandarin (sh)", "Polish", "Sanskrit"],
},
"\u0290": { # ʐ
"place": "retroflex", "manner": "fricative", "voicing": "voiced",
"name": "voiced retroflex fricative",
"spanish": False, "spanish_example": None,
"espeak_code": "z.",
"languages": ["Mandarin (r-)", "Polish", "Russian"],
},
"\u00e7": { # ç
"place": "palatal", "manner": "fricative", "voicing": "voiceless",
"name": "voiceless palatal fricative",
"spanish": False, "spanish_example": None,
"espeak_code": "C",
"languages": ["German (ich)", "Greek", "Japanese (hi)"],
},
"\u029d": { # ʝ
"place": "palatal", "manner": "fricative", "voicing": "voiced",
"name": "voiced palatal fricative",
"spanish": True, "spanish_example": "mayo (some dialects)",
"espeak_code": "j",
"languages": ["Spanish (some dialects)", "Greek", "Irish"],
},
"x": {
"place": "velar", "manner": "fricative", "voicing": "voiceless",
"name": "voiceless velar fricative",
"spanish": True, "spanish_example": "jota",
"espeak_code": "x",
"languages": ["Spanish", "German (Bach)", "Russian", "Arabic"],
},
"\u0263": { # ɣ
"place": "velar", "manner": "fricative", "voicing": "voiced",
"name": "voiced velar fricative",
"spanish": True, "spanish_example": "lago (allophone of /g/)",
"espeak_code": "Q",
"languages": ["Spanish (allophone)", "Greek", "Irish"],
},
"\u03c7": { # χ
"place": "uvular", "manner": "fricative", "voicing": "voiceless",
"name": "voiceless uvular fricative",
"spanish": False, "spanish_example": None,
"espeak_code": "X",
"languages": ["German (some dialects)", "Hebrew", "Welsh"],
},
"\u0281": { # ʁ
"place": "uvular", "manner": "fricative", "voicing": "voiced",
"name": "voiced uvular fricative",
"spanish": False, "spanish_example": None,
"espeak_code": "g\"",
"languages": ["French (r)", "German (r)", "Dutch"],
},
"\u0127": { # ħ
"place": "pharyngeal", "manner": "fricative", "voicing": "voiceless",
"name": "voiceless pharyngeal fricative",
"spanish": False, "spanish_example": None,
"espeak_code": "H",
"languages": ["Arabic (ح)", "Hebrew", "Somali"],
},
"\u0295": { # ʕ
"place": "pharyngeal", "manner": "fricative", "voicing": "voiced",
"name": "voiced pharyngeal fricative",
"spanish": False, "spanish_example": None,
"espeak_code": "Q\"",
"languages": ["Arabic (ع)", "Hebrew", "Somali"],
},
"h": {
"place": "glottal", "manner": "fricative", "voicing": "voiceless",
"name": "voiceless glottal fricative",
"spanish": True, "spanish_example": "huevo (some dialects)",
"espeak_code": "h",
"languages": ["English", "German", "Japanese", "Arabic"],
},
"\u0266": { # ɦ
"place": "glottal", "manner": "fricative", "voicing": "voiced",
"name": "voiced glottal fricative",
"spanish": False, "spanish_example": None,
"espeak_code": "h\\",
"languages": ["Dutch", "Czech", "Ukrainian"],
},
# === LATERAL FRICATIVES ===
"\u026c": { # ɬ
"place": "alveolar", "manner": "lateral fricative", "voicing": "voiceless",
"name": "voiceless alveolar lateral fricative",
"spanish": False, "spanish_example": None,
"espeak_code": "l#",
"languages": ["Welsh (ll)", "Zulu", "Navajo"],
},
"\u026e": { # ɮ
"place": "alveolar", "manner": "lateral fricative", "voicing": "voiced",
"name": "voiced alveolar lateral fricative",
"spanish": False, "spanish_example": None,
"espeak_code": None,
"languages": ["Mongolian", "Zulu"],
},
# === APPROXIMANTS ===
"\u028b": { # ʋ
"place": "labiodental", "manner": "approximant", "voicing": "voiced",
"name": "voiced labiodental approximant",
"spanish": False, "spanish_example": None,
"espeak_code": "v#",
"languages": ["Dutch", "Finnish", "Hindi"],
},
"\u0279": { # ɹ
"place": "alveolar", "manner": "approximant", "voicing": "voiced",
"name": "voiced alveolar approximant",
"spanish": False, "spanish_example": None,
"espeak_code": "r\\",
"languages": ["English (red)", "some Dutch dialects"],
},
"\u027b": { # ɻ
"place": "retroflex", "manner": "approximant", "voicing": "voiced",
"name": "voiced retroflex approximant",
"spanish": False, "spanish_example": None,
"espeak_code": "r\\.",
"languages": ["Tamil", "American English (r)"],
},
"j": {
"place": "palatal", "manner": "approximant", "voicing": "voiced",
"name": "voiced palatal approximant",
"spanish": True, "spanish_example": "yo (some dialects)",
"espeak_code": "j\\",
"languages": ["English (yes)", "Spanish", "French", "German"],
},
"w": {
"place": "velar", "manner": "approximant", "voicing": "voiced",
"name": "voiced labial-velar approximant",
"spanish": True, "spanish_example": "huevo",
"espeak_code": "w",
"languages": ["English", "Spanish", "French", "Mandarin"],
},
# === LATERAL APPROXIMANTS ===
"l": {
"place": "alveolar", "manner": "lateral approximant", "voicing": "voiced",
"name": "voiced alveolar lateral approximant",
"spanish": True, "spanish_example": "luna",
"espeak_code": "l",
"languages": ["English", "Spanish", "French", "German"],
},
"\u026d": { # ɭ
"place": "retroflex", "manner": "lateral approximant", "voicing": "voiced",
"name": "voiced retroflex lateral approximant",
"spanish": False, "spanish_example": None,
"espeak_code": "l.",
"languages": ["Tamil", "Hindi", "Norwegian"],
},
"\u028e": { # ʎ
"place": "palatal", "manner": "lateral approximant", "voicing": "voiced",
"name": "voiced palatal lateral approximant",
"spanish": True, "spanish_example": "calle (traditional)",
"espeak_code": "l^",
"languages": ["Spanish (traditional)", "Italian", "Portuguese", "Catalan"],
},
"\u029f": { # ʟ
"place": "velar", "manner": "lateral approximant", "voicing": "voiced",
"name": "voiced velar lateral approximant",
"spanish": False, "spanish_example": None,
"espeak_code": "L",
"languages": ["Mid-Waghi", "some PNG languages"],
},
}
# =============================================================================
# VOWEL CHART DATA
# =============================================================================
# Vowel height levels (top to bottom)
VOWEL_HEIGHTS = ["close", "near-close", "close-mid", "mid", "open-mid", "near-open", "open"]
# Vowel backness levels (left to right)
VOWEL_BACKNESSES = ["front", "central", "back"]
# Full IPA vowel data
VOWELS = {
# === CLOSE VOWELS ===
"i": {
"height": "close", "backness": "front", "rounding": "unrounded",
"name": "close front unrounded vowel",
"spanish": True, "spanish_example": "sí",
"espeak_code": "i",
"languages": ["English (see)", "Spanish", "French", "German"],
},
"y": {
"height": "close", "backness": "front", "rounding": "rounded",
"name": "close front rounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "y",
"languages": ["French (tu)", "German (über)", "Finnish", "Mandarin (ü)"],
},
"\u0268": { # ɨ
"height": "close", "backness": "central", "rounding": "unrounded",
"name": "close central unrounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "i\"",
"languages": ["Russian (ы)", "Polish", "Romanian"],
},
"\u0289": { # ʉ
"height": "close", "backness": "central", "rounding": "rounded",
"name": "close central rounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "u\"",
"languages": ["Swedish", "Norwegian", "some English dialects"],
},
"\u026f": { # ɯ
"height": "close", "backness": "back", "rounding": "unrounded",
"name": "close back unrounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "u-",
"languages": ["Turkish", "Japanese", "Korean"],
},
"u": {
"height": "close", "backness": "back", "rounding": "rounded",
"name": "close back rounded vowel",
"spanish": True, "spanish_example": "tú",
"espeak_code": "u",
"languages": ["English (boot)", "Spanish", "French", "German"],
},
# === NEAR-CLOSE VOWELS ===
"\u026a": { # ɪ
"height": "near-close", "backness": "front", "rounding": "unrounded",
"name": "near-close front unrounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "I",
"languages": ["English (bit)", "German"],
},
"\u028f": { # ʏ
"height": "near-close", "backness": "front", "rounding": "rounded",
"name": "near-close front rounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "Y",
"languages": ["German (hübsch)", "Swedish"],
},
"\u028a": { # ʊ
"height": "near-close", "backness": "back", "rounding": "rounded",
"name": "near-close back rounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "U",
"languages": ["English (book)", "German"],
},
# === CLOSE-MID VOWELS ===
"e": {
"height": "close-mid", "backness": "front", "rounding": "unrounded",
"name": "close-mid front unrounded vowel",
"spanish": True, "spanish_example": "mesa",
"espeak_code": "e",
"languages": ["Spanish", "French (été)", "German (Beet)", "Italian"],
},
"\u00f8": { # ø
"height": "close-mid", "backness": "front", "rounding": "rounded",
"name": "close-mid front rounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "Y\"",
"languages": ["French (peu)", "German (schön)", "Danish", "Finnish"],
},
"\u0258": { # ɘ
"height": "close-mid", "backness": "central", "rounding": "unrounded",
"name": "close-mid central unrounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": None,
"languages": ["Korean", "Paicî"],
},
"\u0275": { # ɵ
"height": "close-mid", "backness": "central", "rounding": "rounded",
"name": "close-mid central rounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": None,
"languages": ["Swedish", "Australian English"],
},
"\u0264": { # ɤ
"height": "close-mid", "backness": "back", "rounding": "unrounded",
"name": "close-mid back unrounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "o-",
"languages": ["Korean", "Vietnamese", "Thai"],
},
"o": {
"height": "close-mid", "backness": "back", "rounding": "rounded",
"name": "close-mid back rounded vowel",
"spanish": True, "spanish_example": "como",
"espeak_code": "o",
"languages": ["Spanish", "French (beau)", "German (Boot)", "Italian"],
},
# === MID VOWEL ===
"\u0259": { # ə (schwa)
"height": "mid", "backness": "central", "rounding": "unrounded",
"name": "mid central vowel (schwa)",
"spanish": False, "spanish_example": None,
"espeak_code": "@",
"languages": ["English (about)", "French (le)", "German (bitte)"],
},
# === OPEN-MID VOWELS ===
"\u025b": { # ɛ
"height": "open-mid", "backness": "front", "rounding": "unrounded",
"name": "open-mid front unrounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "E",
"languages": ["English (bed)", "French (fête)", "Italian"],
},
"\u0153": { # œ
"height": "open-mid", "backness": "front", "rounding": "rounded",
"name": "open-mid front rounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "W",
"languages": ["French (peur)", "German (Hölle)"],
},
"\u025c": { # ɜ
"height": "open-mid", "backness": "central", "rounding": "unrounded",
"name": "open-mid central unrounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "3",
"languages": ["English (bird - British)"],
},
"\u025e": { # ɞ
"height": "open-mid", "backness": "central", "rounding": "rounded",
"name": "open-mid central rounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": None,
"languages": ["Irish", "some English dialects"],
},
"\u028c": { # ʌ
"height": "open-mid", "backness": "back", "rounding": "unrounded",
"name": "open-mid back unrounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "V",
"languages": ["English (but)", "Korean"],
},
"\u0254": { # ɔ
"height": "open-mid", "backness": "back", "rounding": "rounded",
"name": "open-mid back rounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "O",
"languages": ["English (thought)", "French (mort)", "Italian"],
},
# === NEAR-OPEN VOWELS ===
"\u00e6": { # æ
"height": "near-open", "backness": "front", "rounding": "unrounded",
"name": "near-open front unrounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "a#",
"languages": ["English (cat)", "Danish", "Arabic"],
},
"\u0250": { # ɐ
"height": "near-open", "backness": "central", "rounding": "unrounded",
"name": "near-open central vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "a\"",
"languages": ["German (bitter)", "Portuguese", "some English dialects"],
},
# === OPEN VOWELS ===
"a": {
"height": "open", "backness": "front", "rounding": "unrounded",
"name": "open front unrounded vowel",
"spanish": True, "spanish_example": "casa",
"espeak_code": "a",
"languages": ["Spanish", "French (patte)", "Italian", "German"],
},
"\u0276": { # ɶ
"height": "open", "backness": "front", "rounding": "rounded",
"name": "open front rounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": None,
"languages": ["Danish", "some German dialects"],
},
"\u0251": { # ɑ
"height": "open", "backness": "back", "rounding": "unrounded",
"name": "open back unrounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "A",
"languages": ["English (father)", "French (pâte)", "Persian"],
},
"\u0252": { # ɒ
"height": "open", "backness": "back", "rounding": "rounded",
"name": "open back rounded vowel",
"spanish": False, "spanish_example": None,
"espeak_code": "A.",
"languages": ["British English (lot)", "Hungarian"],
},
}
# =============================================================================
# VOWEL TRAPEZOID COORDINATES (for SVG rendering)
# =============================================================================
# SVG viewBox: 0 0 500 400
# The trapezoid is narrower at top (close) and wider at bottom (open)
# x increases left-to-right (front → back), y increases top-to-bottom (close → open)
VOWEL_TRAPEZOID_COORDS = {
# (x, y) positions on the trapezoid SVG
# Close row
("close", "front"): (80, 40),
("close", "central"): (250, 40),
("close", "back"): (420, 40),
# Near-close row
("near-close", "front"): (110, 95),
("near-close", "back"): (400, 95),
# Close-mid row
("close-mid", "front"): (130, 145),
("close-mid", "central"): (255, 145),
("close-mid", "back"): (380, 145),
# Mid row
("mid", "central"): (260, 200),
# Open-mid row
("open-mid", "front"): (170, 250),
("open-mid", "central"): (265, 250),
("open-mid", "back"): (360, 250),
# Near-open row
("near-open", "front"): (195, 305),
("near-open", "central"): (270, 305),
# Open row
("open", "front"): (215, 355),
("open", "back"): (340, 355),
}
# =============================================================================
# HELPER FUNCTIONS
# =============================================================================
def get_consonant_at(place, manner, voicing):
"""Get the IPA symbol for a consonant at a specific position in the chart."""
for symbol, data in CONSONANTS.items():
if data["place"] == place and data["manner"] == manner and data["voicing"] == voicing:
return symbol
return None
def get_vowel_at(height, backness, rounding):
"""Get the IPA symbol for a vowel at a specific position in the chart."""
for symbol, data in VOWELS.items():
if data["height"] == height and data["backness"] == backness and data["rounding"] == rounding:
return symbol
return None
def get_spanish_consonants():
"""Return all consonants that appear in Spanish."""
return {sym: data for sym, data in CONSONANTS.items() if data["spanish"]}
def get_spanish_vowels():
"""Return all vowels that appear in Spanish."""
return {sym: data for sym, data in VOWELS.items() if data["spanish"]}
def get_all_spanish_phonemes():
"""Return all Spanish phonemes (consonants + vowels)."""
return {**get_spanish_consonants(), **get_spanish_vowels()}
def get_phoneme_info(symbol):
"""Look up any IPA symbol and return its full data."""
if symbol in CONSONANTS:
return {"type": "consonant", **CONSONANTS[symbol]}
if symbol in VOWELS:
return {"type": "vowel", **VOWELS[symbol]}
return None