I want to get the errors made when writing a static text, in this case ( hola soy el texto estatico de prueba
). My problem occurs when back/backspace is pressed, it stops working.
I check if it is a space so that the error does not affect the entire sentence but only the word. Example:
hola como
and I writeola como
, then everything would be wrong because the entire sentence is moved 1 position, however there is only 1 error, which is theh
.
texto estatico texto escrito respuesta resp actual
hola soy el texto hla soy el texto error-> o -----l error->ola---la
In the previous case, the user only made a mistake in writing the letter "o", but his mistake affected the whole word. To try to solve it, I obtain the positions of the beginnings of the words with the function
getPosiciones()
that so that the error produced, which in this case was only the lettero
, does not affect the entire sentence; Now it only affects the word, but it's still wrong, it should affect 1 letter and not the whole word .
var texto = document.getElementById('captureInput');
var index = 0;
var errores = [];
var textoEstatico = "hola soy el texto estatico de prueba";
var posiciones = [];
var indexActual = 0;
var flagDoubleEspacio = false;
function is_special_key(key_id) {
var tecladoEspecial=[8,9,13,17,18,19,27,33,34,35,36,37,38,39,40,45,46,91,93,112,113,114,115,116,117,118,119,120,121,122,123,145];
if(tecladoEspecial.indexOf(key_id)==0){
return true;
}
return false;
}
function esLaMisma(key_id, texto, i) {
var res = false;
if (key_id == texto.charAt(i)) {
res = true;
}
return res;
}
function posicionPalabras(texto, done) {
var posiciones = [];
var ini, fin, cp, tamPalabras = 0;
ini = fin = 0, cp = 0;
var copiaEstatica, palabra = "";
var arrayEstatico = textoEstatico.split(" ");
var arregloPosiciones = []
for (var i = 0; i < arrayEstatico.length; i++) {
tamPalabras = arrayEstatico[i].length - 1;
if (fin == 0) {
fin = fin + tamPalabras + 1;
} else {
fin = fin + tamPalabras + 2;
}
var auxPos = {
ini,
fin
};
palabra = arrayEstatico[i];
arregloPosiciones.push({
palabra: palabra,
posiciones: auxPos
});
ini = fin + 1;
};
return done(null, arregloPosiciones);
}
function buscarPalabra(mapeo, indice, done) {
getPosiciones();
var intervalIni = 0,
intervalFin = 0;
mapeo.forEach(function(current, index, verdadero) {
intervalIni = current.posiciones.ini;
intervalFin = current.posiciones.fin;
if (indice >= intervalIni && indice <= intervalFin) {
return done(null, current.palabra)
}
})
}
texto.addEventListener('keydown', function(keyboardEvent) {
if (!is_special_key(keyboardEvent.keyCode)) {
flagDoubleEspacio = true;
let keyC = keyboardEvent.key;
if ((!esLaMisma(keyC, textoEstatico, index))) {
arregloPosiciones = posicionPalabras(textoEstatico, function(err, result) {
buscarPalabra(result, index, function(err, res) {
let simbol = textoEstatico.charAt(index);
let mensaje = 'palabra: ' + res + ' \tletra Original: ' + simbol + ' \tletra erronea: ' + keyC;
mostrarMensaje(mensaje, "erroresFrecuentes");
errores.push({
palabra: res,
posiciones: {
simbol,
keyC
}
});
});
});
}
} else {
if (keyboardEvent.keyCode == 8) { //backspace
index -= 2;
}
}
if (keyboardEvent.keyCode == 32) { //espacio
if (flagDoubleEspacio) {
index = posiciones[indexActual];
indexActual++;
flagDoubleEspacio = false;
}
} else {
index++;
}
});
function mostrarMensaje(mensaje, caja) {
var contenedor = document.getElementById(caja);
var res = contenedor.innerText.split('\n');
res.push(mensaje);
contenedor.innerText = res.join('\n');
contenedor.scrollTop = contenedor.scrollHeight - contenedor.clientHeight;
}
function getPosiciones() {
for (var i = 0; i <= textoEstatico.length - 1; i++) {
if (textoEstatico.charAt(i) == " ") {
posiciones.push(i + 1);
}
}
}
<p>hola soy el texto estatico de prueba</p>
<textarea id="captureInput" placeholde="escribe aqui"></textarea>
<pre id="erroresFrecuentes" style="overflow-y: scroll; height:200px;"></pre>
Well, your correction function is somewhat ambitious, I imagine that you will have to perform a set of validations as independent functions to finally obtain more precise information about the error, here is an implementation that can help you in part by finding inconsistent characters, like this :
I suppose that it will solve part of your problem at least by defining which characters are missing and in what position they should be found, however it will fail to add new characters for example
Now I hope you find the contribution useful and can attach it to the list of validations of your proofreader.
PS: Adaptation for the solution
Now it should be clear that it still has the limitations posed for adding new characters, but it solves the inconvenience presented for the backspace key by not depending on the typed position, but on the complete comparison of the terms in the sentence.
The problem is because when a character is omitted, the value of
index
no longer matches for the rest of the characters in the word. The way to fix this is to add one to the value ofindex
(index +=1;
) when a character has been skipped. One way to do this is to add the blockelse
including the following toif
the function statementesLaMisma
:Putting the above into the code, it would look like this:
Esta solución encara el problema de una forma diferente.
En lugar de concentrarse en el caracter agregado, por cada caracter agregado se busca las diferencias en toda la frase buscando sincronizar lo mejor posible los dos textos de forma de no arrastrar errores.
Para hacer esto se basa el la forma en que funcionan los programas que comparan archivos de texto como Diff.
Dadas dos cadenas se utiliza una algoritmo para encontrar la secuencia mas larga de caracteres comunes y a partir de ahí comparar esa secuencia con las dos cadenas para detectar que caracteres fueron eliminados y que caracteres fueron agregados (mal tipeados).
Llevadolo al planteo que se quiere resolver aquí, cualquiera de los dos casos se trata de un error.
La ventaja de implementar esta solución es que un error al principio del texto solo será propagado hasta donde el texto se vuelve a sincronizar.
Y también se evita tener que hacer un análisis de cada tecla digitada y ocuparse de casos extremos (edge cases) porque lo que interesa es el texto completo directamente y hasta donde coincide con el texto original.
El nombre del algoritmo es "Longest Common Subsequence" (LCS) -Más larga subsecuencia comúm-.
Particularmente para la pregutna porté a javascript la implementación en Java que está en esta página.
En wikipedia también hay más información sobre como funciona el algoritmo.
EDICION 1
Me quedó un poco abajo la referencia de como entender la salida del programa así que lo agrego aquí:
"Los errores se marcan con un signo menos ("-") cuando faltan letras respecto del texto original, y con un signo más ("+") cuando se han agregado letras. La porción de texto agregado o quitado está entre corchetes ("[]")"
EDICION 2
Respuesta al comentario:
Es posible presentar una salida parecida a la de la pregunta bajando el nivel de comparación al nivel de palabras.
La salida sería diferente en que debe contemplar letras agregadas (1 o más), letras quitadas (1 o más), además de letras reemplazadas.
También hay que tomar una decisión de compromiso respecto de qué se compara con qué dado que las dos cadenas pueden tener diferente cantidad de palabras producto de omitir un espacio, tipear un espacio incorrecto dentro de una palabra válida, agregar palabras que no están en el texto original, u omitiendo palabras completas. A diferencia de los humanos la computadora no puede inferir por contexto si es un error o dos palabras o una palabra que se repitió dos veces.
Una forma puede ser seguir estas reglas:
Entonces se podría dar este ejemplo:
Patrón: "hola soy el texto estatico de prueba"
Texto ingresado: "hlr soy l txto de de de prueba"
Compara: hola soy el texto estatico de prueba
Con: hlr soy l txto de de de prueba
Diferencias detectadas:
hola: h-[o]l-[a]+[r]
el: -[e]l
texto: t-[e]xto
estatico: +[d]e-[statico]
prueba: -[pru]+[d]e-[ba]
???: +[prueba]
Luego, las diferencias se pueden parsear o pasar por un autómata finito y tener una salida como:
palabra 'hola': falta/n la/s letra/s 'o', y se reemplazó/aron la/s letra/s 'a' por 'r'.
palabra 'estatico': falta/n la/s letra/s 's','t','a','t','i','c','o', y se agregó/aron la/s letra/s 'd'.
La palabra ingresada 'prueba' quedó desfasada por eso se muestra como faltante con signos de pregunta.
EDICION 3
Para implementar las reglas que se mencionan en la EDICION 2, se modificó el programa para procesar palabra por palabra y también la salida de la función que genera la presentación de las diferencias para mostrarlas de este otro modo. No hizo falta parseo adiciona ni utilizar un autómata finito como se había propuesto.
Dejé la solución original y agregué la solución modificada abajo.