import gradio as gr from gtts import gTTS import tempfile from deep_translator import GoogleTranslator import gradio as gr from gtts import gTTS import tempfile from deep_translator import GoogleTranslator transliteration_map = { # Two-character combinations (check first) 'ch': 'ח', 'ts': 'צ', 'tz': 'צ', 'sh': 'ש', 'kh': 'כ', # Single characters 'a': 'א', 'b': 'ב', 'g': 'ג', 'd': 'ד', 'h': 'ה', 'v': 'ו', 'w': 'ו', 'z': 'ז', 't': 'ט', 'y': 'י', 'k': 'כ', 'l': 'ל', 'm': 'מ', 'n': 'נ', 's': 'ס', 'p': 'פ', 'f': 'פ', 'q': 'ק', 'r': 'ר', # Vowels 'e': 'ֶ', 'i': 'ִ', 'o': 'ֹ', 'u': 'ֻ', # Space and punctuation ' ': ' ', '.': '.', ',': ',', '?': '?', '!': '!' } def generate_letter_audio(hebrew_letter): """Generate TTS audio for a single Hebrew letter or character.""" if not hebrew_letter or not hebrew_letter.strip(): return None try: tts = gTTS(text=hebrew_letter, lang='iw', 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 English text to Hebrew transliteration""" if not text: return "" text = text.lower() result = [] i = 0 while i < len(text): # Check for two-letter combinations first if i < len(text) - 1: two_char = text[i:i+2] if two_char in transliteration_map: result.append(transliteration_map[two_char]) i += 2 continue # Check for single letter char = text[i] if char in transliteration_map: result.append(transliteration_map[char]) elif char == ' ': result.append(' ') else: result.append(char) i += 1 return ''.join(result) def google_translate_hebrew(english_text): """Translate English text to Hebrew 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='iw').translate(english_text) return translation_text except Exception as e: return f"❌ Google Translate error: {str(e)}\n\nPlease check your internet connection and try again." def translate_multiple_words(hebrew_text): """Translate multiple Hebrew words - both individually and as a whole phrase""" if not hebrew_text or not hebrew_text.strip(): return "No text provided for translation." try: # First translate the whole phrase full_translation = GoogleTranslator(source='iw', target='en').translate(hebrew_text) # Then translate individual words if there are multiple words words = hebrew_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='iw', target='en').translate(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(hebrew_text): """Translate Hebrew text to English using Google Translate""" if not hebrew_text or not hebrew_text.strip(): return "No text provided for translation." try: # Translate to English translation_text = GoogleTranslator(source='iw', target='en').translate(hebrew_text) return translation_text except Exception as e: return f"❌ Translation error: {str(e)}" def hebrew_tts(hebrew_text): """Generate TTS audio for Hebrew text.""" if not hebrew_text or not hebrew_text.strip(): return None try: tts = gTTS(text=hebrew_text, lang='iw', 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"Hebrew TTS Error: {e}") return None def transliterate_and_speak(english_text): """Combined function to transliterate and generate audio.""" hebrew_text = transliterate(english_text) hebrew_audio = hebrew_tts(hebrew_text) return hebrew_text, hebrew_audio def full_process_with_translation(english_text, mode): """Complete processing: translate/transliterate, generate audio, and get word translations""" if mode == "Transliteration": hebrew_text = transliterate(english_text) else: hebrew_text = google_translate_hebrew(english_text) hebrew_audio = hebrew_tts(hebrew_text) translation_result = translate_multiple_words(hebrew_text) return hebrew_text, hebrew_audio, translation_result # Create Gradio interface with custom CSS for copy buttons css = """ .copy-btn { font-size: 12px !important; padding: 4px 8px !important; min-width: 60px !important; } """ with gr.Blocks(title="English to Hebrew Converter", css=css) as demo: gr.Markdown("## 📝 English-to-Hebrew Converter") gr.Markdown("Enter English text to convert to Hebrew script, generate audio, and get translations using Google Translate.") # English to Hebrew Letter Mapping Guide with gr.Accordion("🔤 English ↔ Hebrew Letter Mapping Guide", open=False): gr.Markdown(""" ### How English Letters Map to Hebrew This shows the transliteration mapping used in **Transliteration** mode: """) with gr.Row(): with gr.Column(): gr.Markdown(""" #### Consonants: - **a** → א (alef) - **b** → ב (bet) - **g** → ג (gimel) - **d** → ד (dalet) - **h** → ה (he) - **v, w** → ו (vav) - **z** → ז (zayin) - **t** → ט (tet) - **y** → י (yod) - **k** → כ (kaf) - **l** → ל (lamed) - **m** → מ (mem) """) with gr.Column(): gr.Markdown(""" #### More Consonants: - **n** → נ (nun) - **s** → ס (samekh) - **p, f** → פ (pe/fe) - **q** → ק (qof) - **r** → ר (resh) #### Special Combinations: - **ch** → ח (chet) - **kh** → כ (kaf) - **sh** → ש (shin) - **ts, tz** → צ (tsadi) """) with gr.Column(): gr.Markdown(""" #### Vowel Marks: - **e** → ֶ (segol) - **i** → ִ (hiriq) - **o** → ֹ (holam) - **u** → ֻ (kubutz) #### Examples: - **shalom** → שאלֹמ - **hello** → הֶללֹ - **thanks** → טהאנכס """) # Full-width transliteration guide with audio buttons with gr.Accordion("📖 Interactive Hebrew Alphabet Guide with Audio", open=False): gr.Markdown("### Click the speaker buttons to hear each letter's pronunciation:") # Audio component for letter playback letter_audio = gr.Audio(label="Letter Pronunciation", autoplay=True) # Consonants (Row 1) gr.Markdown("#### Consonants:") with gr.Row(): gr.Button("🔊 א alef (a)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("א"), outputs=letter_audio) gr.Button("🔊 ב bet (b)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ב"), outputs=letter_audio) gr.Button("🔊 ג gimel (g)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ג"), outputs=letter_audio) gr.Button("🔊 ד dalet (d)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ד"), outputs=letter_audio) gr.Button("🔊 ה he (h)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ה"), outputs=letter_audio) # Consonants (Row 2) with gr.Row(): gr.Button("🔊 ו vav (v/w)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ו"), outputs=letter_audio) gr.Button("🔊 ז zayin (z)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ז"), outputs=letter_audio) gr.Button("🔊 ח chet (ch)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ח"), outputs=letter_audio) gr.Button("🔊 ט tet (t)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ט"), outputs=letter_audio) gr.Button("🔊 י yod (y)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("י"), outputs=letter_audio) # Consonants (Row 3) with gr.Row(): gr.Button("🔊 כ kaf (k/kh)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("כ"), outputs=letter_audio) gr.Button("🔊 ל lamed (l)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ל"), outputs=letter_audio) gr.Button("🔊 מ mem (m)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("מ"), outputs=letter_audio) gr.Button("🔊 נ nun (n)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("נ"), outputs=letter_audio) gr.Button("🔊 ס samekh (s)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ס"), outputs=letter_audio) # Consonants (Row 4) with gr.Row(): gr.Button("🔊 ע ayin", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ע"), outputs=letter_audio) gr.Button("🔊 פ pe (p/f)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("פ"), outputs=letter_audio) gr.Button("🔊 צ tsadi (ts/tz)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("צ"), outputs=letter_audio) gr.Button("🔊 ק qof (q)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ק"), outputs=letter_audio) gr.Button("🔊 ר resh (r)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ר"), outputs=letter_audio) # Consonants (Row 5) with gr.Row(): gr.Button("🔊 ש shin (sh)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ש"), outputs=letter_audio) gr.Button("🔊 ת tav (t)", size="sm").click(fn=generate_letter_audio, inputs=gr.State("ת"), outputs=letter_audio) # Mode selection mode = gr.Radio( choices=["Translation", "Transliteration"], value="Transliteration", label="Conversion Mode" ) # Main interface with copy buttons with gr.Row(): with gr.Column(): with gr.Row(): english_input = gr.Textbox( label="Enter English Text", lines=3, placeholder="Example: Hello, how are you?", scale=5 ) copy_english_btn = gr.Button("📋 Copy", size="sm", scale=1, elem_classes="copy-btn") with gr.Column(): with gr.Row(): hebrew_output = gr.Textbox( label="Hebrew Script", lines=3, rtl=True, scale=5 ) copy_hebrew_btn = gr.Button("📋 Copy", size="sm", scale=1, elem_classes="copy-btn") # Translation output with copy button with gr.Row(): translation_output = gr.Textbox( label="Word-by-Word Translation Results", lines=3, placeholder="Translations will appear here...", scale=5 ) copy_translation_btn = gr.Button("📋 Copy", size="sm", scale=1, elem_classes="copy-btn") # Button controls with gr.Row(): convert_btn = gr.Button("🔄 Convert", variant="primary") tts_btn = gr.Button("🔊 Generate Hebrew Sound", variant="secondary") translate_btn = gr.Button("🌐 Google Translate", variant="secondary") with gr.Row(): combined_btn = gr.Button("🔄🔊 Convert & Speak", variant="secondary") complete_btn = gr.Button("🔄🌐🔊 Complete Process (Audio + Translation)", variant="primary") # Audio output with gr.Row(): hebrew_audio = gr.Audio(label="Hebrew Audio", type="filepath") # Manual translation section with gr.Accordion("🔍 Manual Hebrew to English Translation", open=False): with gr.Row(): with gr.Column(): with gr.Row(): manual_hebrew_input = gr.Textbox( label="Enter Hebrew text to translate", placeholder="הכנס טקסט בעברית", rtl=True, lines=3, scale=5 ) copy_manual_hebrew_btn = gr.Button("📋 Copy", size="sm", scale=1, elem_classes="copy-btn") manual_translate_btn = gr.Button("🌐 Translate to English", variant="secondary") with gr.Column(): with gr.Row(): manual_translation_output = gr.Textbox( label="English Translation", lines=3, scale=5 ) copy_manual_translation_btn = gr.Button("📋 Copy", size="sm", scale=1, elem_classes="copy-btn") # Event handlers def process_convert(text, mode): if mode == "Transliteration": return transliterate(text) else: return google_translate_hebrew(text) # Copy button functions copy_english_btn.click(fn=lambda x: x, inputs=english_input, outputs=english_input, js="(x) => {navigator.clipboard.writeText(x); return x;}") copy_hebrew_btn.click(fn=lambda x: x, inputs=hebrew_output, outputs=hebrew_output, js="(x) => {navigator.clipboard.writeText(x); return x;}") copy_translation_btn.click(fn=lambda x: x, inputs=translation_output, outputs=translation_output, js="(x) => {navigator.clipboard.writeText(x); return x;}") copy_manual_hebrew_btn.click(fn=lambda x: x, inputs=manual_hebrew_input, outputs=manual_hebrew_input, js="(x) => {navigator.clipboard.writeText(x); return x;}") copy_manual_translation_btn.click(fn=lambda x: x, inputs=manual_translation_output, outputs=manual_translation_output, js="(x) => {navigator.clipboard.writeText(x); return x;}") convert_btn.click( fn=process_convert, inputs=[english_input, mode], outputs=hebrew_output ) tts_btn.click( fn=hebrew_tts, inputs=hebrew_output, outputs=hebrew_audio ) translate_btn.click( fn=translate_multiple_words, inputs=hebrew_output, outputs=translation_output ) combined_btn.click( fn=lambda text, mode: transliterate_and_speak(text) if mode == "Transliteration" else (google_translate_hebrew(text), hebrew_tts(google_translate_hebrew(text))), inputs=[english_input, mode], outputs=[hebrew_output, hebrew_audio] ) complete_btn.click( fn=full_process_with_translation, inputs=[english_input, mode], outputs=[hebrew_output, hebrew_audio, translation_output] ) manual_translate_btn.click( fn=reverse_translate_english, inputs=manual_hebrew_input, outputs=manual_translation_output ) if __name__ == "__main__": demo.launch()