Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| from mtranslate import translate | |
| from bs4 import BeautifulSoup, NavigableString | |
| import re | |
| import time | |
| import html | |
| # Diccionario de idiomas y sus códigos | |
| lang_dict = { | |
| 'Auto': 'auto', | |
| 'Español': 'es', | |
| 'English': 'en', | |
| 'Francés': 'fr', | |
| 'Alemán': 'de', | |
| 'Italiano': 'it', | |
| 'Portugués': 'pt', | |
| 'Chino': 'zh', | |
| 'Japonés': 'ja', | |
| 'Ruso': 'ru', | |
| } | |
| lang_list = list(lang_dict.keys()) | |
| source_lang_list = ['Auto'] + lang_list | |
| # --- FUNCIONES --- | |
| def split_text(text, limit=4000): | |
| sentences = re.split(r'([;.])', text) | |
| chunks = [] | |
| chunk = '' | |
| for i in range(0, len(sentences), 2): | |
| sentence = sentences[i] + (sentences[i+1] if i+1 < len(sentences) else '') | |
| if len(chunk) + len(sentence) > limit: | |
| chunks.append(chunk) | |
| chunk = '' | |
| chunk += sentence | |
| if chunk: | |
| chunks.append(chunk) | |
| return chunks | |
| def translate_html_content(text, source_lang, target_lang): | |
| soup = BeautifulSoup(text, 'html.parser') | |
| for node in soup.find_all(string=True): # Cambiado de text=True a string=True | |
| if isinstance(node, NavigableString) and node.strip(): | |
| original_text = node.strip() | |
| chunks = split_text(original_text) | |
| translated_chunks = [translate(chunk, target_lang, source_lang) for chunk in chunks] | |
| translated_text = ''.join(translated_chunks) | |
| # Verificar espacios antes y después del nodo | |
| if node.previous_sibling and isinstance(node.previous_sibling, NavigableString): | |
| translated_text = ' ' + translated_text | |
| if node.next_sibling and isinstance(node.next_sibling, NavigableString): # Verificación corregida | |
| if not node.next_sibling.startswith(' '): | |
| translated_text += ' ' | |
| node.replace_with(translated_text) | |
| return str(soup) | |
| def main(): | |
| st.title("🌍 Traductor HTML Inteligente") | |
| with st.expander("ℹ️ Instrucciones"): | |
| st.write( | |
| "- Introduce tu texto o HTML en la caja de texto.\n" | |
| "- Selecciona el idioma de origen y el idioma de destino.\n" | |
| "- Haz clic en 'Traducir' para obtener el texto traducido." | |
| ) | |
| text = st.text_area("✍️ Introduce el texto o HTML aquí:", height=200) | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| source_lang = st.selectbox("🌐 Idioma de origen:", source_lang_list) | |
| with col2: | |
| target_lang = st.selectbox("🎯 Idioma de destino:", lang_list, index=1) | |
| if st.button("🚀 Traducir"): | |
| if text.strip(): | |
| with st.spinner("⏳ Traduciendo..."): | |
| translated_text = translate_html_content(text, lang_dict[source_lang], lang_dict[target_lang]) | |
| st.session_state.translated_text = translated_text | |
| time.sleep(2) # Simulación de carga | |
| st.subheader("📝 Resultado de la traducción:") | |
| st.write(translated_text) | |
| # Botón de copiar | |
| copy_button = f""" | |
| <button onclick="copyToClipboard()">📋 Copiar</button> | |
| <script> | |
| function copyToClipboard() {{ | |
| var text = `{html.escape(translated_text)}`; | |
| navigator.clipboard.writeText(text).then(function() {{ | |
| alert('Texto copiado al portapapeles'); | |
| }}, function(err) {{ | |
| console.error('No se pudo copiar el texto: ', err); | |
| }}); | |
| }} | |
| </script> | |
| """ | |
| st.markdown(copy_button, unsafe_allow_html=True) | |
| else: | |
| st.warning("⚠️ Por favor, introduce un texto antes de traducir.") | |
| if "translated_text" not in st.session_state: | |
| st.session_state.translated_text = "" | |
| # Ejecutar la app | |
| main() | |