|
|
import gradio as gr |
|
|
from gtts import gTTS |
|
|
import tempfile |
|
|
import os |
|
|
from deep_translator import GoogleTranslator |
|
|
|
|
|
|
|
|
translit_map = { |
|
|
|
|
|
"TH": "ث", "KH": "خ", "DH": "ذ", "SH": "ش", "GH": "غ", |
|
|
"AA": "آ", "EE": "ي", "OO": "و", "UU": "و", "II": "ي", |
|
|
|
|
|
|
|
|
"a": "ا", "b": "ب", "c": "ك", "t": "ت", "j": "ج", "H": "ح", |
|
|
"d": "د", "r": "ر", "z": "ز", "s": "س", |
|
|
"S": "ص", "D": "ض", "T": "ط", "Z": "ظ", |
|
|
"'": "ع", "f": "ف", "q": "ق", "k": "ك", |
|
|
"l": "ل", "m": "م", "n": "ن", "h": "ه", |
|
|
"w": "و", "y": "ي", "x": "ء", |
|
|
|
|
|
|
|
|
"i": "إِ", "u": "أُ", "e": "أ", "o": "أُ", |
|
|
|
|
|
|
|
|
"I": "ِ", "U": "ُ","O": "ُ", "A": "َ", "~": "ّ", "^": "ْ", |
|
|
|
|
|
|
|
|
"AN": "ً", "UN": "ٌ","ON": "ٌ", "IN": "ٍ", |
|
|
|
|
|
|
|
|
" ": " ", ".": ".", ",": "،", "?": "؟", "!": "!" |
|
|
} |
|
|
|
|
|
|
|
|
latin_to_ipa = { |
|
|
|
|
|
"TH": "θ", |
|
|
"KH": "x", |
|
|
"DH": "ð", |
|
|
"SH": "ʃ", |
|
|
"GH": "ɣ", |
|
|
|
|
|
|
|
|
"AA": "aː", |
|
|
"EE": "iː", |
|
|
"OO": "uː", |
|
|
"UU": "uː", |
|
|
"II": "iː", |
|
|
|
|
|
|
|
|
"b": "b", |
|
|
"t": "t", |
|
|
"j": "dʒ", |
|
|
"H": "ħ", |
|
|
"d": "d", |
|
|
"r": "r", |
|
|
"z": "z", |
|
|
"s": "s", |
|
|
"S": "sˤ", |
|
|
"D": "dˤ", |
|
|
"T": "tˤ", |
|
|
"Z": "ðˤ", |
|
|
"'": "ʕ", |
|
|
"f": "f", |
|
|
"q": "q", |
|
|
"k": "k", |
|
|
"l": "l", |
|
|
"m": "m", |
|
|
"n": "n", |
|
|
"h": "h", |
|
|
"w": "w", |
|
|
"y": "j", |
|
|
"x": "ʔ", |
|
|
|
|
|
|
|
|
"a": "a", |
|
|
"i": "i", |
|
|
"u": "u", |
|
|
"e": "a", |
|
|
"o": "u", |
|
|
|
|
|
|
|
|
"A": "a", |
|
|
"I": "i", |
|
|
"U": "u", |
|
|
"~": "ː", |
|
|
"^": "", |
|
|
|
|
|
|
|
|
"AN": "an", |
|
|
"UN": "un", |
|
|
"IN": "in", |
|
|
|
|
|
|
|
|
" ": " ", |
|
|
".": ".", |
|
|
",": ",", |
|
|
"?": "?", |
|
|
"!": "!" |
|
|
} |
|
|
|
|
|
|
|
|
arabic_to_buckwalter = { |
|
|
|
|
|
'ا': 'A', 'ب': 'b', 'ت': 't', 'ث': 'v', 'ج': 'j', 'ح': 'H', 'خ': 'x', |
|
|
'د': 'd', 'ذ': '*', 'ر': 'r', 'ز': 'z', 'س': 's', 'ش': '$', 'ص': 'S', |
|
|
'ض': 'D', 'ط': 'T', 'ظ': 'Z', 'ع': 'E', 'غ': 'g', 'ف': 'f', 'ق': 'q', |
|
|
'ك': 'k', 'ل': 'l', 'م': 'm', 'ن': 'n', 'ه': 'h', 'و': 'w', 'ي': 'y', |
|
|
|
|
|
|
|
|
'ء': "'", 'أ': '>', 'إ': '<', 'آ': '|', 'ؤ': '&', 'ئ': '}', |
|
|
|
|
|
|
|
|
'ة': 'p', |
|
|
|
|
|
|
|
|
'ى': 'Y', |
|
|
|
|
|
|
|
|
'َ': 'a', 'ُ': 'u', 'ِ': 'i', 'ً': 'F', 'ٌ': 'N', 'ٍ': 'K', |
|
|
'ّ': '~', 'ْ': 'o', |
|
|
|
|
|
|
|
|
'،': ',', '؛': ';', '؟': '?', '«': '"', '»': '"', |
|
|
|
|
|
|
|
|
' ': ' ', '٠': '0', '١': '1', '٢': '2', '٣': '3', '٤': '4', |
|
|
'٥': '5', '٦': '6', '٧': '7', '٨': '8', '٩': '9' |
|
|
} |
|
|
|
|
|
|
|
|
buckwalter_to_arabic = {v: k for k, v in arabic_to_buckwalter.items()} |
|
|
|
|
|
def clean_arabic_text(text): |
|
|
"""Remove diacritics from Arabic text for translation""" |
|
|
if not text: |
|
|
return "" |
|
|
|
|
|
|
|
|
diacritics = "ًٌٍَُِّْ" |
|
|
cleaned = text |
|
|
for diacritic in diacritics: |
|
|
cleaned = cleaned.replace(diacritic, "") |
|
|
|
|
|
return cleaned.strip() |
|
|
|
|
|
def google_translate_arabic(arabic_text): |
|
|
""" |
|
|
Translate Arabic text to English using Google Translate |
|
|
Returns translation and detected language info |
|
|
""" |
|
|
if not arabic_text or not arabic_text.strip(): |
|
|
return "No text provided for translation." |
|
|
|
|
|
try: |
|
|
|
|
|
clean_text = clean_arabic_text(arabic_text) |
|
|
|
|
|
try: |
|
|
translation_text = GoogleTranslator(source='ar', target='en').translate(clean_text) |
|
|
detection_lang = GoogleTranslator(source='auto', target='en').detect(clean_text) |
|
|
except: |
|
|
detection_lang = 'ar' |
|
|
translation_text = GoogleTranslator(source='ar', target='en').translate(clean_text) |
|
|
|
|
|
|
|
|
result = translation_text |
|
|
|
|
|
return result |
|
|
|
|
|
except Exception as e: |
|
|
return f"❌ Google Translate error: {str(e)}\n\nPlease check your internet connection and try again." |
|
|
|
|
|
def translate_multiple_words(arabic_text): |
|
|
""" |
|
|
Translate multiple Arabic words - both individually and as a whole phrase |
|
|
""" |
|
|
if not arabic_text or not arabic_text.strip(): |
|
|
return "No text provided for translation." |
|
|
|
|
|
try: |
|
|
|
|
|
full_translation = google_translate_arabic(arabic_text) |
|
|
|
|
|
|
|
|
words = arabic_text.strip().split() |
|
|
|
|
|
if len(words) > 1: |
|
|
individual_translations = [] |
|
|
for i, word in enumerate(words[:5], 1): |
|
|
if len(word.strip()) > 1: |
|
|
try: |
|
|
word_translation = GoogleTranslator(source='ar', target='en').translate(clean_arabic_text(word)) |
|
|
individual_translations.append(f"**{i}. {word}** → {word_translation}") |
|
|
except: |
|
|
individual_translations.append(f"**{i}. {word}** → (translation failed)") |
|
|
|
|
|
if individual_translations: |
|
|
result = full_translation + "\n\n" + "─"*50 + "\n\n" |
|
|
result += "📝 **Individual Word Translations:**\n\n" |
|
|
result += "\n".join(individual_translations) |
|
|
return result |
|
|
|
|
|
return full_translation |
|
|
|
|
|
except Exception as e: |
|
|
return f"❌ Translation error: {str(e)}" |
|
|
|
|
|
def reverse_translate_english(english_text): |
|
|
""" |
|
|
Translate English text to Arabic using Google Translate |
|
|
""" |
|
|
if not english_text or not english_text.strip(): |
|
|
return "No text provided for translation." |
|
|
|
|
|
try: |
|
|
|
|
|
translation_text = GoogleTranslator(source='en', target='ar').translate(english_text) |
|
|
|
|
|
|
|
|
result = translation_text |
|
|
|
|
|
return result, translation_text |
|
|
|
|
|
except Exception as e: |
|
|
return f"❌ Translation error: {str(e)}", "" |
|
|
|
|
|
def generate_letter_audio(arabic_letter): |
|
|
"""Generate TTS audio for a single Arabic letter or character.""" |
|
|
if not arabic_letter or not arabic_letter.strip(): |
|
|
return None |
|
|
|
|
|
try: |
|
|
tts = gTTS(text=arabic_letter, lang='ar', slow=True) |
|
|
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_file: |
|
|
temp_path = tmp_file.name |
|
|
tts.save(temp_path) |
|
|
return temp_path |
|
|
except Exception as e: |
|
|
print(f"Letter TTS Error: {e}") |
|
|
return None |
|
|
|
|
|
def transliterate(text): |
|
|
"""Convert Latin text to Arabic script using transliteration mapping.""" |
|
|
if not text: |
|
|
return "" |
|
|
|
|
|
output = "" |
|
|
i = 0 |
|
|
|
|
|
while i < len(text): |
|
|
|
|
|
if i + 1 < len(text) and text[i:i+2] in translit_map: |
|
|
output += translit_map[text[i:i+2]] |
|
|
i += 2 |
|
|
|
|
|
elif text[i] in translit_map: |
|
|
output += translit_map[text[i]] |
|
|
i += 1 |
|
|
else: |
|
|
|
|
|
output += text[i] |
|
|
i += 1 |
|
|
|
|
|
return output |
|
|
|
|
|
def latin_to_ipa_conversion(latin_text): |
|
|
"""Convert Latin text directly to IPA phonetic transcription.""" |
|
|
if not latin_text: |
|
|
return "" |
|
|
|
|
|
output = "" |
|
|
i = 0 |
|
|
|
|
|
while i < len(latin_text): |
|
|
|
|
|
if i + 1 < len(latin_text) and latin_text[i:i+2] in latin_to_ipa: |
|
|
output += latin_to_ipa[latin_text[i:i+2]] |
|
|
i += 2 |
|
|
|
|
|
elif latin_text[i] in latin_to_ipa: |
|
|
output += latin_to_ipa[latin_text[i]] |
|
|
i += 1 |
|
|
else: |
|
|
|
|
|
output += latin_text[i] |
|
|
i += 1 |
|
|
|
|
|
return output |
|
|
|
|
|
def arabic_to_buckwalter_convert(arabic_text): |
|
|
"""Convert Arabic text to Buckwalter transliteration.""" |
|
|
if not arabic_text: |
|
|
return "" |
|
|
|
|
|
result = "" |
|
|
for char in arabic_text: |
|
|
if char in arabic_to_buckwalter: |
|
|
result += arabic_to_buckwalter[char] |
|
|
else: |
|
|
result += char |
|
|
|
|
|
return result |
|
|
|
|
|
def buckwalter_to_arabic_convert(buckwalter_text): |
|
|
"""Convert Buckwalter transliteration to Arabic text.""" |
|
|
if not buckwalter_text: |
|
|
return "" |
|
|
|
|
|
result = "" |
|
|
for char in buckwalter_text: |
|
|
if char in buckwalter_to_arabic: |
|
|
result += buckwalter_to_arabic[char] |
|
|
else: |
|
|
result += char |
|
|
|
|
|
return result |
|
|
|
|
|
def bidirectional_buckwalter_convert(input_text): |
|
|
"""Automatically detect and convert between Arabic and Buckwalter.""" |
|
|
if not input_text.strip(): |
|
|
return "" |
|
|
|
|
|
|
|
|
|
|
|
has_arabic = any('\u0600' <= char <= '\u06FF' for char in input_text) |
|
|
|
|
|
if has_arabic: |
|
|
|
|
|
return arabic_to_buckwalter_convert(input_text) |
|
|
else: |
|
|
|
|
|
return buckwalter_to_arabic_convert(input_text) |
|
|
|
|
|
def arabic_tts(arabic_text): |
|
|
"""Generate TTS audio for Arabic text.""" |
|
|
if not arabic_text or not arabic_text.strip(): |
|
|
return None |
|
|
|
|
|
try: |
|
|
tts = gTTS(text=arabic_text, lang='ar', slow=False) |
|
|
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_file: |
|
|
temp_path = tmp_file.name |
|
|
tts.save(temp_path) |
|
|
return temp_path |
|
|
except Exception as e: |
|
|
print(f"Arabic TTS Error: {e}") |
|
|
return None |
|
|
|
|
|
def ipa_tts(ipa_text): |
|
|
"""Generate TTS audio for IPA text using English TTS.""" |
|
|
if not ipa_text or not ipa_text.strip(): |
|
|
return None |
|
|
|
|
|
try: |
|
|
tts = gTTS(text=ipa_text, lang='en', slow=True) |
|
|
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_file: |
|
|
temp_path = tmp_file.name |
|
|
tts.save(temp_path) |
|
|
return temp_path |
|
|
except Exception as e: |
|
|
print(f"IPA TTS Error: {e}") |
|
|
return None |
|
|
|
|
|
def transliterate_and_speak(latin_text): |
|
|
"""Combined function to transliterate and generate audio.""" |
|
|
arabic_text = transliterate(latin_text) |
|
|
ipa_text = latin_to_ipa_conversion(latin_text) |
|
|
arabic_audio = arabic_tts(arabic_text) |
|
|
return arabic_text, ipa_text, arabic_audio |
|
|
|
|
|
def full_process_with_ipa_audio(latin_text): |
|
|
"""Process text and generate both Arabic and IPA audio.""" |
|
|
arabic_text = transliterate(latin_text) |
|
|
ipa_text = latin_to_ipa_conversion(latin_text) |
|
|
arabic_audio = arabic_tts(arabic_text) |
|
|
ipa_audio = ipa_tts(ipa_text) |
|
|
return arabic_text, ipa_text, arabic_audio, ipa_audio |
|
|
|
|
|
def full_process_with_translation(latin_text): |
|
|
"""Complete processing: transliterate, generate audio, and translate with Google.""" |
|
|
arabic_text = transliterate(latin_text) |
|
|
ipa_text = latin_to_ipa_conversion(latin_text) |
|
|
arabic_audio = arabic_tts(arabic_text) |
|
|
ipa_audio = ipa_tts(ipa_text) |
|
|
translation_result = translate_multiple_words(arabic_text) |
|
|
return arabic_text, ipa_text, arabic_audio, ipa_audio, translation_result |
|
|
|
|
|
|
|
|
with gr.Blocks(title="Arabic Transliterator with Google Translate") as demo: |
|
|
gr.Markdown("## 📝 Latin-to-Arabic Transliterator with Google Translate") |
|
|
gr.Markdown("Enter Latin characters to convert to Arabic script, generate audio, and get translations using Google Translate.") |
|
|
|
|
|
|
|
|
with gr.Accordion("📖 Interactive Transliteration Guide with Audio", open=False): |
|
|
gr.Markdown("### Click the speaker buttons to hear each letter's pronunciation:") |
|
|
|
|
|
gr.Markdown(""" |
|
|
**💡 Note:** The built-in IPA audio uses English TTS reading of IPA symbols. |
|
|
For accurate Arabic phoneme pronunciation, see the links below the IPA output. |
|
|
""") |
|
|
|
|
|
|
|
|
gr.Markdown("#### Two-Character Combinations:") |
|
|
with gr.Row(): |
|
|
with gr.Column(scale=1): |
|
|
gr.Button("🔊 TH → ث", size="sm").click( |
|
|
fn=generate_letter_audio, inputs=gr.State("ث"), outputs=gr.Audio(visible=False, autoplay=True) |
|
|
) |
|
|
with gr.Column(scale=1): |
|
|
gr.Button("🔊 KH → خ", size="sm").click( |
|
|
fn=generate_letter_audio, inputs=gr.State("خ"), outputs=gr.Audio(visible=False, autoplay=True) |
|
|
) |
|
|
with gr.Column(scale=1): |
|
|
gr.Button("🔊 DH → ذ", size="sm").click( |
|
|
fn=generate_letter_audio, inputs=gr.State("ذ"), outputs=gr.Audio(visible=False, autoplay=True) |
|
|
) |
|
|
with gr.Column(scale=1): |
|
|
gr.Button("🔊 SH → ش", size="sm").click( |
|
|
fn=generate_letter_audio, inputs=gr.State("ش"), outputs=gr.Audio(visible=False, autoplay=True) |
|
|
) |
|
|
with gr.Column(scale=1): |
|
|
gr.Button("🔊 GH → غ", size="sm").click( |
|
|
fn=generate_letter_audio, inputs=gr.State("غ"), outputs=gr.Audio(visible=False, autoplay=True) |
|
|
) |
|
|
|
|
|
|
|
|
gr.Markdown("#### Long Vowels:") |
|
|
with gr.Row(): |
|
|
with gr.Column(scale=1): |
|
|
gr.Button("🔊 AA → آ", size="sm").click( |
|
|
fn=generate_letter_audio, inputs=gr.State("آ"), outputs=gr.Audio(visible=False, autoplay=True) |
|
|
) |
|
|
with gr.Column(scale=1): |
|
|
gr.Button("🔊 EE → ي", size="sm").click( |
|
|
fn=generate_letter_audio, inputs=gr.State("ي"), outputs=gr.Audio(visible=False, autoplay=True) |
|
|
) |
|
|
with gr.Column(scale=1): |
|
|
gr.Button("🔊 OO → و", size="sm").click( |
|
|
fn=generate_letter_audio, inputs=gr.State("و"), outputs=gr.Audio(visible=False, autoplay=True) |
|
|
) |
|
|
with gr.Column(scale=1): |
|
|
gr.Button("🔊 UU → و", size="sm").click( |
|
|
fn=generate_letter_audio, inputs=gr.State("و"), outputs=gr.Audio(visible=False, autoplay=True) |
|
|
) |
|
|
with gr.Column(scale=1): |
|
|
gr.Button("🔊 II → ي", size="sm").click( |
|
|
fn=generate_letter_audio, inputs=gr.State("ي"), outputs=gr.Audio(visible=False, autoplay=True) |
|
|
) |
|
|
|
|
|
|
|
|
gr.Markdown("#### Basic Consonants:") |
|
|
with gr.Row(): |
|
|
gr.Button("🔊 a → ا", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ا"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 b → ب", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ب"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 t → ت", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ت"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 j → ج", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ج"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 H → ح", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ح"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
|
|
|
|
|
|
with gr.Row(): |
|
|
gr.Button("🔊 d → د", size="sm").click(fn=generate_letter_audio, inputs=gr.State("د"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 c → ك", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ك"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 r → ر", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ر"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 z → ز", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ز"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 s → س", size="sm").click(fn=generate_letter_audio, inputs=gr.State("س"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 f → ف", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ف"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
|
|
|
|
|
|
with gr.Row(): |
|
|
gr.Button("🔊 q → ق", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ق"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 k → ك", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ك"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 l → ل", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ل"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 m → م", size="sm").click(fn=generate_letter_audio, inputs=gr.State("م"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 n → ن", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ن"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
|
|
|
|
|
|
with gr.Row(): |
|
|
gr.Button("🔊 h → ه", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ه"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 w → و", size="sm").click(fn=generate_letter_audio, inputs=gr.State("و"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 y → ي", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ي"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 ' → ع", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ع"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 x → ء", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ء"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
|
|
|
|
|
|
gr.Markdown("#### Emphatic Consonants (Capital Letters):") |
|
|
with gr.Row(): |
|
|
gr.Button("🔊 S → ص", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ص"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 D → ض", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ض"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 T → ط", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ط"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 Z → ظ", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ظ"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
|
|
|
|
|
|
gr.Markdown("#### Initial Vowels (Word Beginnings):") |
|
|
with gr.Row(): |
|
|
gr.Button("🔊 i → إِ", size="sm").click(fn=generate_letter_audio, inputs=gr.State("إِ"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 u → أُ", size="sm").click(fn=generate_letter_audio, inputs=gr.State("أُ"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 e → أ", size="sm").click(fn=generate_letter_audio, inputs=gr.State("أ"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 o → أُ", size="sm").click(fn=generate_letter_audio, inputs=gr.State("أُ"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
|
|
|
|
|
|
gr.Markdown("#### Tanween (Double Diacritics):") |
|
|
with gr.Row(): |
|
|
gr.Button("🔊 AN → ً", size="sm").click(fn=generate_letter_audio, inputs=gr.State("بً"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 UN → ٌ", size="sm").click(fn=generate_letter_audio, inputs=gr.State("بٌ"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 IN → ٍ", size="sm").click(fn=generate_letter_audio, inputs=gr.State("بٍ"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
gr.Button("🔊 ON → ٍ", size="sm").click(fn=generate_letter_audio, inputs=gr.State("بٌ"), outputs=gr.Audio(visible=False, autoplay=True)) |
|
|
|
|
|
|
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(): |
|
|
latin_input = gr.Textbox( |
|
|
show_copy_button=True, |
|
|
label="Enter Latin-encoded Arabic", |
|
|
lines=3, |
|
|
placeholder="Example: ehlaAN w sAhlaAN (أهلا وسهلا)" |
|
|
|
|
|
) |
|
|
|
|
|
with gr.Column(): |
|
|
arabic_output = gr.Textbox( |
|
|
show_copy_button=True, |
|
|
label="Arabic Script", |
|
|
lines=3, |
|
|
rtl=True |
|
|
) |
|
|
|
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(): |
|
|
ipa_output = gr.Textbox( |
|
|
show_copy_button=True, |
|
|
label="IPA Phonetic Transcription", |
|
|
lines=2, |
|
|
placeholder="Shows how the Arabic sounds should be pronounced using IPA symbols" |
|
|
) |
|
|
with gr.Column(): |
|
|
translation_output = gr.Textbox( |
|
|
show_copy_button=True, |
|
|
label="Google Translate Results", |
|
|
lines=2, |
|
|
placeholder="Translations will appear here...", |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
with gr.Row(): |
|
|
convert_btn = gr.Button("🔄 Transliterate", variant="primary") |
|
|
tts_btn = gr.Button("🔊 Generate Arabic Sound", variant="secondary") |
|
|
ipa_btn = gr.Button("🔤 Generate IPA Text", variant="secondary") |
|
|
translate_btn = gr.Button("🌐 Google Translate", variant="secondary") |
|
|
|
|
|
with gr.Row(): |
|
|
combined_btn = gr.Button("🔄🔊 Transliterate & Speak", variant="secondary") |
|
|
full_process_btn = gr.Button("🔄🔤🔊 Full Process (IPA Audio)", variant="secondary") |
|
|
complete_btn = gr.Button("🔄🌐🔊 Complete Process (IPA Audio + Translation)", variant="primary") |
|
|
|
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(): |
|
|
arabic_audio = gr.Audio(label="Arabic Audio", type="filepath") |
|
|
with gr.Column(): |
|
|
ipa_audio = gr.Audio(label="IPA Pronunciation Audio (English reading)", type="filepath") |
|
|
|
|
|
|
|
|
with gr.Accordion("🔄 Buckwalter Transliteration", open=False): |
|
|
gr.Markdown("**Bi-directional Arabic ↔ Buckwalter transliteration**") |
|
|
gr.Markdown("Enter Arabic text or Buckwalter notation. The system will auto-detect and convert.") |
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(): |
|
|
buckwalter_input = gr.Textbox( |
|
|
label="Input (Arabic or Buckwalter)", |
|
|
lines=3, |
|
|
show_copy_button=True |
|
|
) |
|
|
|
|
|
with gr.Column(): |
|
|
buckwalter_output = gr.Textbox( |
|
|
label="Converted Output", |
|
|
lines=3, |
|
|
show_copy_button=True |
|
|
) |
|
|
|
|
|
buckwalter_convert_btn = gr.Button("🔄 Convert", variant="primary") |
|
|
|
|
|
|
|
|
|
|
|
with gr.Accordion("🔍 Manual Translation", open=False): |
|
|
with gr.Row(): |
|
|
with gr.Column(): |
|
|
manual_arabic_input = gr.Textbox( |
|
|
label="Enter Arabic text to translate", |
|
|
placeholder="Enter Arabic text for English translation", |
|
|
rtl=True |
|
|
) |
|
|
manual_translate_btn = gr.Button("🌐 Translate to English", variant="secondary") |
|
|
|
|
|
with gr.Column(): |
|
|
manual_english_input = gr.Textbox( |
|
|
label="Enter English text to translate", |
|
|
placeholder="Enter English text for Arabic translation" |
|
|
) |
|
|
reverse_translate_btn = gr.Button("🌐 Translate to Arabic", variant="secondary") |
|
|
|
|
|
manual_translation_output = gr.Textbox( |
|
|
label="Manual Translation Results", |
|
|
lines=6, |
|
|
show_copy_button=True |
|
|
) |
|
|
|
|
|
manual_arabic_result = gr.Textbox( |
|
|
label="Translated Arabic Text", |
|
|
rtl=True, |
|
|
visible=False |
|
|
) |
|
|
|
|
|
|
|
|
with gr.Accordion("🎯 Free IPA Pronunciation Tools (More Accurate)", open=False): |
|
|
gr.Markdown(""" |
|
|
**🌐 Online (No Download Required):** |
|
|
• **[IPA Reader](https://ipa-reader.com/)** - Copy/paste IPA for high-quality speech |
|
|
• **[Phoneme Synthesis](https://itinerarium.github.io/phoneme-synthesis/)** - Real-time IPA → audio |
|
|
• **[Seeing Speech](https://www.seeingspeech.ac.uk/ipa-charts/)** - University tool with visual articulation |
|
|
|
|
|
**💡 How to use:** Copy the IPA text from above and paste it into any of these tools for accurate Arabic phoneme pronunciation! |
|
|
""") |
|
|
|
|
|
|
|
|
convert_btn.click( |
|
|
fn=transliterate, |
|
|
inputs=latin_input, |
|
|
outputs=arabic_output |
|
|
) |
|
|
|
|
|
ipa_btn.click( |
|
|
fn=latin_to_ipa_conversion, |
|
|
inputs=latin_input, |
|
|
outputs=ipa_output |
|
|
) |
|
|
|
|
|
tts_btn.click( |
|
|
fn=arabic_tts, |
|
|
inputs=arabic_output, |
|
|
outputs=arabic_audio |
|
|
) |
|
|
|
|
|
translate_btn.click( |
|
|
fn=translate_multiple_words, |
|
|
inputs=arabic_output, |
|
|
outputs=translation_output |
|
|
) |
|
|
|
|
|
combined_btn.click( |
|
|
fn=transliterate_and_speak, |
|
|
inputs=latin_input, |
|
|
outputs=[arabic_output, ipa_output, arabic_audio] |
|
|
) |
|
|
|
|
|
full_process_btn.click( |
|
|
fn=full_process_with_ipa_audio, |
|
|
inputs=latin_input, |
|
|
outputs=[arabic_output, ipa_output, arabic_audio, ipa_audio] |
|
|
) |
|
|
|
|
|
complete_btn.click( |
|
|
fn=full_process_with_translation, |
|
|
inputs=latin_input, |
|
|
outputs=[arabic_output, ipa_output, arabic_audio, ipa_audio, translation_output] |
|
|
) |
|
|
|
|
|
|
|
|
buckwalter_convert_btn.click( |
|
|
fn=bidirectional_buckwalter_convert, |
|
|
inputs=buckwalter_input, |
|
|
outputs=[buckwalter_output] |
|
|
) |
|
|
|
|
|
|
|
|
manual_translate_btn.click( |
|
|
fn=translate_multiple_words, |
|
|
inputs=manual_arabic_input, |
|
|
outputs=manual_translation_output |
|
|
) |
|
|
|
|
|
reverse_translate_btn.click( |
|
|
fn=reverse_translate_english, |
|
|
inputs=manual_english_input, |
|
|
outputs=[manual_translation_output, manual_arabic_result] |
|
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch() |