# modules/morphosyntax/morphosyntax_interface.py import streamlit as st import re import logging from spacy import displacy # Importa tu pipeline de spacy, por ejemplo: # nlp_models = {"es": spacy.load("es_core_news_sm")} # Supongamos que estas funciones existen en tus otros módulos: from ..morphosyntax.morphosyntax_process import perform_advanced_morphosyntactic_analysis from ..database.morphosyntax_iterative_mongo_db import ( store_student_morphosyntax_base, store_student_morphosyntax_iteration, ) logger = logging.getLogger(__name__) ########################################################################### def initialize_arc_analysis_state(): """ Inicializa el estado de análisis de arcos (base e iteraciones) si no existe. """ if "arc_analysis_state" not in st.session_state: st.session_state.arc_analysis_state = { "base_id": None, # ObjectId del documento base "base_text": "", # Texto inicial "base_diagram": None, # HTML del diagrama base "iteration_text": "", # Texto de iteración "iteration_diagram": None, # HTML del diagrama de iteración } logger.info("Estado de análisis de arcos inicializado.") ########################################################################### def reset_arc_analysis_state(): """ Resetea completamente el estado de análisis de arcos. """ st.session_state.arc_analysis_state = { "base_id": None, "base_text": "", "base_diagram": None, "iteration_text": "", "iteration_diagram": None, } ########################################################################### def display_arc_diagram(doc): """ Genera y retorna el HTML del diagrama de arco para un `Doc` de spaCy. No imprime directamente en pantalla; regresa el HTML para que se renderice con `st.write(..., unsafe_allow_html=True)`. """ try: diagram_html = "" for sent in doc.sents: svg_html = displacy.render( sent, style="dep", options={ "distance": 100, "arrow_spacing": 20, "word_spacing": 30, } ) # Ajustar tamaño y posición svg_html = svg_html.replace('height="375"', 'height="200"') svg_html = re.sub( r']*>', lambda m: m.group(0).replace('height="450"', 'height="300"'), svg_html ) svg_html = re.sub( r']*transform="translate\((\d+),(\d+)\)"', lambda m: f'{svg_html}' return diagram_html except Exception as e: logger.error(f"Error en display_arc_diagram: {str(e)}") return "

Error generando diagrama

" ########################################################################### def display_morphosyntax_interface(lang_code, nlp_models): """ Interfaz principal para la visualización de diagramas de arco (Texto Base vs Iteraciones). """ # CSS para layout estable st.markdown(""" """, unsafe_allow_html=True) # Inicializar el estado si no existe initialize_arc_analysis_state() arc_state = st.session_state.arc_analysis_state # Para abreviar # Creamos pestañas: "Texto Base" y "Iteraciones" tabs = st.tabs(["Texto Base", "Iteraciones"]) # ------------------- PESTAÑA 1: Texto Base -------------------------- with tabs[0]: st.subheader("Análisis de Texto Base") # Botón para resetear todo if st.button("Nuevo Análisis", key="btn_reset_base"): reset_arc_analysis_state() st.experimental_rerun() # Input para texto base arc_state["base_text"] = st.text_area( "Ingrese su texto inicial", value=arc_state["base_text"], key="base_text_input", height=120 ) # Botón de análisis base if st.button("Analizar Texto Base", key="btn_analyze_base"): if not arc_state["base_text"].strip(): st.warning("Ingrese un texto para analizar.") else: try: # Procesar con spaCy doc = nlp_models[lang_code](arc_state["base_text"]) # Generar HTML del arco base_arc_html = display_arc_diagram(doc) arc_state["base_diagram"] = base_arc_html # Guardar en BD usando tu análisis avanzado analysis = perform_advanced_morphosyntactic_analysis( arc_state["base_text"], nlp_models[lang_code] ) base_id = store_student_morphosyntax_base( username=st.session_state.username, text=arc_state["base_text"], arc_diagrams=analysis["arc_diagrams"] ) if base_id: arc_state["base_id"] = base_id st.success(f"Análisis base guardado con ID: {base_id}") except Exception as e: st.error("Error procesando texto base") logger.error(f"Error en análisis base: {str(e)}") # Mostrar el arco base, si existe if arc_state["base_diagram"]: st.markdown("
", unsafe_allow_html=True) st.markdown("#### Diagrama de Arco (Texto Base)") st.write(arc_state["base_diagram"], unsafe_allow_html=True) # ------------------- PESTAÑA 2: Iteraciones ------------------------- with tabs[1]: st.subheader("Análisis de Cambios / Iteraciones") # Si no se ha analizado nada en la primera pestaña if not arc_state["base_id"]: st.info("Primero analiza un texto base en la pestaña anterior.") return # Mostrar el texto base como referencia, en modo solo lectura st.text_area( "Texto Base (solo lectura)", value=arc_state["base_text"], key="base_text_ref", height=80, disabled=True ) # Texto de iteración arc_state["iteration_text"] = st.text_area( "Texto de Iteración", value=arc_state["iteration_text"], key="iteration_text_input", height=120 ) # Botón para analizar iteración if st.button("Analizar Cambios", key="btn_analyze_iteration"): if not arc_state["iteration_text"].strip(): st.warning("Ingrese texto de iteración.") else: try: # Procesar con spaCy doc_iter = nlp_models[lang_code](arc_state["iteration_text"]) iteration_arc_html = display_arc_diagram(doc_iter) arc_state["iteration_diagram"] = iteration_arc_html # Guardar en BD iteration_analysis = perform_advanced_morphosyntactic_analysis( arc_state["iteration_text"], nlp_models[lang_code] ) iteration_id = store_student_morphosyntax_iteration( username=st.session_state.username, base_id=arc_state["base_id"], original_text=arc_state["base_text"], iteration_text=arc_state["iteration_text"], arc_diagrams=iteration_analysis["arc_diagrams"] ) if iteration_id: st.success(f"Iteración guardada con ID: {iteration_id}") except Exception as e: st.error("Error procesando iteración") logger.error(f"Error en iteración: {str(e)}") # Mostrar el arco de iteración, si existe if arc_state["iteration_diagram"]: st.markdown("
", unsafe_allow_html=True) st.markdown("#### Diagrama de Arco (Iteración)") st.write(arc_state["iteration_diagram"], unsafe_allow_html=True) # Mostrar comparación (opcional) if arc_state["base_diagram"] and arc_state["iteration_diagram"]: st.markdown("
", unsafe_allow_html=True) st.markdown("### Comparación de Diagrama Base vs. Iteración") col_base, col_iter = st.columns(2) with col_base: st.markdown("**Diagrama Base**") st.write(arc_state["base_diagram"], unsafe_allow_html=True) with col_iter: st.markdown("**Diagrama Iterado**") st.write(arc_state["iteration_diagram"], unsafe_allow_html=True)