import gradio as gr from gtts import gTTS import tempfile import os from deep_translator import GoogleTranslator # Enhanced transliteration map with proper Arabic characters translit_map = { # Two-character combinations (must be checked first) "TH": "ث", "KH": "خ", "DH": "ذ", "SH": "ش", "GH": "غ", "AA": "آ", "EE": "ي", "OO": "و", "UU": "و", "II": "ي", # Single characters "a": "ا", "b": "ب", "c": "ك", "t": "ت", "j": "ج", "H": "ح", "d": "د", "r": "ر", "z": "ز", "s": "س", "S": "ص", "D": "ض", "T": "ط", "Z": "ظ", "'": "ع", "f": "ف", "q": "ق", "k": "ك", "l": "ل", "m": "م", "n": "ن", "h": "ه", "w": "و", "y": "ي", "x": "ء", # Initial vowels (hamza with vowel for word beginnings) "i": "إِ", "u": "أُ", "e": "أ", "o": "أُ", # Short vowels (diacritics) "I": "ِ", "U": "ُ","O": "ُ", "A": "َ", "~": "ّ", "^": "ْ", # Tanween (double diacritics) "AN": "ً", "UN": "ٌ","ON": "ٌ", "IN": "ٍ", # Space and punctuation " ": " ", ".": ".", ",": "،", "?": "؟", "!": "!" } # Proper Arabic romanization to IPA mapping latin_to_ipa = { # Two-character combinations (must be checked first) "TH": "θ", # ث - voiceless dental fricative "KH": "x", # خ - voiceless velar fricative "DH": "ð", # ذ - voiced dental fricative "SH": "ʃ", # ش - voiceless postalveolar fricative "GH": "ɣ", # غ - voiced velar fricative # Long vowels "AA": "aː", # آ - long a "EE": "iː", # long i "OO": "uː", # long u "UU": "uː", # long u (alternative) "II": "iː", # long i (alternative) # Consonants "b": "b", # ب "t": "t", # ت "j": "dʒ", # ج "H": "ħ", # ح - voiceless pharyngeal fricative "d": "d", # د "r": "r", # ر - trill "z": "z", # ز "s": "s", # س "S": "sˤ", # ص - emphatic s "D": "dˤ", # ض - emphatic d "T": "tˤ", # ط - emphatic t "Z": "ðˤ", # ظ - emphatic dh "'": "ʕ", # ع - voiced pharyngeal fricative "f": "f", # ف "q": "q", # ق - uvular stop "k": "k", # ك "l": "l", # ل "m": "m", # م "n": "n", # ن "h": "h", # ه "w": "w", # و "y": "j", # ي "x": "ʔ", # ء - glottal stop # Short vowels (context-dependent) "a": "a", # فتحة "i": "i", # كسرة "u": "u", # ضمة "e": "a", # often represents fatha "o": "u", # often represents damma # Diacritics when explicitly marked "A": "a", # explicit fatha "I": "i", # explicit kasra "U": "u", # explicit damma "~": "ː", # shadda (gemination) "^": "", # sukun (no vowel) # Tanween "AN": "an", # فتحتان "UN": "un", # ضمتان "IN": "in", # كسرتان # Space and punctuation " ": " ", ".": ".", ",": ",", "?": "?", "!": "!" } # Buckwalter transliteration mappings arabic_to_buckwalter = { # Basic letters 'ا': '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', # Hamza variants 'ء': "'", 'أ': '>', 'إ': '<', 'آ': '|', 'ؤ': '&', 'ئ': '}', # Taa marbuta 'ة': 'p', # Alif maqsura 'ى': 'Y', # Diacritics 'َ': 'a', 'ُ': 'u', 'ِ': 'i', 'ً': 'F', 'ٌ': 'N', 'ٍ': 'K', 'ّ': '~', 'ْ': 'o', # Punctuation '،': ',', '؛': ';', '؟': '?', '«': '"', '»': '"', # Spaces and numbers ' ': ' ', '٠': '0', '١': '1', '٢': '2', '٣': '3', '٤': '4', '٥': '5', '٦': '6', '٧': '7', '٨': '8', '٩': '9' } # Reverse mapping for Buckwalter to Arabic 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 "" # Remove common Arabic diacritics 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 the text 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) # Format the result 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: # First translate the whole phrase full_translation = google_translate_arabic(arabic_text) # Then translate individual words if there are multiple words words = arabic_text.strip().split() if len(words) > 1: individual_translations = [] for i, word in enumerate(words[:5], 1): # Limit to first 5 words if len(word.strip()) > 1: # Skip single characters 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: # Translate to Arabic translation_text = GoogleTranslator(source='en', target='ar').translate(english_text) # Format the result 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): # Check for two-character combinations first if i + 1 < len(text) and text[i:i+2] in translit_map: output += translit_map[text[i:i+2]] i += 2 # Then check for single characters elif text[i] in translit_map: output += translit_map[text[i]] i += 1 else: # Keep unknown characters as-is 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): # Check for two-character combinations first 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 # Then check for single characters elif latin_text[i] in latin_to_ipa: output += latin_to_ipa[latin_text[i]] i += 1 else: # Keep unknown characters as-is 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 # Keep unknown characters as-is 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 # Keep unknown characters as-is return result def bidirectional_buckwalter_convert(input_text): """Automatically detect and convert between Arabic and Buckwalter.""" if not input_text.strip(): return "" # Simple detection: if text contains Arabic characters, convert to Buckwalter # Otherwise, assume it's Buckwalter and convert to Arabic has_arabic = any('\u0600' <= char <= '\u06FF' for char in input_text) if has_arabic: # Arabic to Buckwalter return arabic_to_buckwalter_convert(input_text) else: # Buckwalter to Arabic 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 # Create Gradio interface 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.") # Full-width transliteration guide with audio buttons 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. """) # Two-character combinations 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) ) # Long vowels 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) ) # Basic consonants (Row 1) 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)) # Basic consonants (Row 2) 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)) # Basic consonants (Row 3) 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)) # Basic consonants (Row 4) 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)) # Emphatic consonants 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)) # Initial vowels 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)) # Tanween 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)) # Main interface 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 # Right-to-left text direction for Arabic ) # IPA output row 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...", ) # Button controls 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") # Audio outputs 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") # Buckwalter transliteration section 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") # Manual translation section 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 ) # External IPA resources 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! """) # Event handlers 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 conversion handler buckwalter_convert_btn.click( fn=bidirectional_buckwalter_convert, inputs=buckwalter_input, outputs=[buckwalter_output] ) # Manual translation handlers 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()