"""Elegir de una lista por voz, y buscar dentro de un fichero (Ctrl+F). La capa que le faltaba a las acciones de fichero. Buscar y soltar el primer resultado no sirve cuando hay varios: hace falta enseñar la lista y poder decir "abre el tercero". Y para buscar DENTRO de un fichero como con Ctrl+F, hace falta recordar cual era. Aqui va la logica pura —interpretar "el tercero", detectar las ordenes de seleccion y de busqueda interna—; el estado (la ultima lista, el ultimo fichero) y la ejecucion viven en el panel. """ import re # Como se dice cada posicion. Se aceptan el ordinal, el numero en palabra y la # cifra, porque el reconocedor devuelve cualquiera de los tres. ORDINALES = { 1: ["primero", "primera", "uno", "1"], 2: ["segundo", "segunda", "dos", "2"], 3: ["tercero", "tercera", "tres", "3"], 4: ["cuarto", "cuarta", "cuatro", "4"], 5: ["quinto", "quinta", "cinco", "5"], 6: ["sexto", "sexta", "seis", "6"], 7: ["septimo", "septima", "siete", "7"], 8: ["octavo", "octava", "ocho", "8"], 9: ["noveno", "novena", "nueve", "9"], 10: ["decimo", "decima", "diez", "10"], } _PALABRA_A_N = {p: n for n, ps in ORDINALES.items() for p in ps} # "el ultimo" es comodo y no es un numero _ULTIMO = {"ultimo", "ultima", "final"} def posicion(texto: str): """Devuelve el numero (1..N) que se ha dicho, -1 para 'el ultimo', o None. Se queda con la PRIMERA posicion mencionada, para que "abre el tercero" de 3 y no se lie con otros numeros que puedan venir detras. """ for palabra in texto.split(): if palabra in _ULTIMO: return -1 if palabra in _PALABRA_A_N: return _PALABRA_A_N[palabra] return None # Ordenes que actuan sobre la lista ya mostrada. El verbo dice que hacer con lo # elegido; la posicion, cual. _ABRIR = re.compile(r"\b(abre|abreme|abrir)\b") _LEER = re.compile(r"\b(lee|leeme|leer|muestrame|ensename)\b") _SELECCION = re.compile(r"\b(el|la|numero|opcion|resultado)\b") def orden_de_seleccion(texto: str): """(accion, posicion) si el texto elige de la lista, o None. accion: "abrir" o "leer". posicion: 1..N o -1 (ultimo). Ejemplos: "abre el tercero", "lee el numero dos", "el ultimo", "abre el 3". """ pos = posicion(texto) if pos is None: return None # tiene que sonar a seleccion, no a otra cosa que lleve un numero if not (_SELECCION.search(texto) or _ABRIR.search(texto) or _LEER.search(texto)): return None if _LEER.search(texto): return ("leer", pos) # por defecto, elegir es abrir return ("abrir", pos) # Ctrl+F: buscar un termino dentro del ultimo fichero abierto. _DENTRO = re.compile( r"\b(busca|buscame|encuentra)\b.*\b(dentro|en el fichero|en el archivo|en el texto)\b") def orden_buscar_dentro(texto: str): """El termino a buscar dentro del fichero, o None. "busca dentro configuracion", "busca en el texto la palabra error". Se queda con lo que va despues de 'dentro'/'en el ...'. """ if not _DENTRO.search(texto): return None # cortar por el separador y quedarse con el resto for sep in ("dentro de", "dentro", "en el fichero", "en el archivo", "en el texto", "la palabra"): if sep in texto: resto = texto.split(sep, 1)[1].strip() resto = re.sub(r"^(la palabra|el termino|de|la|el|los|las)\s+", "", resto).strip() if resto: return resto return None