Así que este engendro carece de sentido práctico; los números no pueden servir de referencia para nadie, porque cambian para cada navegador, para cada resolución y configuración. Pero el desafío estaba bueno, así que desempolvé viejas carpetas y terminé de darle forma a alguno de los experimentos que se sugirieron por acá. Como éste
Código HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd"> <html> <head> <meta http-equiv=Content-Type content="text/html; charset=utf-8"> <title>NUMERA LÍNEAS 1.</title> <script type="text/javascript"> var hoja, numerado, altura, numLinea, espera; var texto0 = ""; // GUARDA TEXTO ORIGINAL var texto1 = []; // TEXTO CON ETIQUETAS SEPARADAS var separador = "¥Ñ"; // CADENA QUE NO SE REPITA EN TEXTO (PARA SEPARAR TAGS) function inicia() { hoja = document.getElementById("pagina"); numerado = document.getElementById("regla"); /* LIMPIA LA BARRA CON NÚMEROS DE LÍNEA */ numerado.innerHTML = ""; /* REINICIA NUMERACIÓN DE LÍNEAS */ numLinea = 1; /* REINICIA DISTANCIA AL TOP DE CADA ESPACIO (PARA CALCULAR NUEVA LÍNEA) */ altura = 0; /* EXTRAE TEXTO ORIGINAL */ texto0 = hoja.innerHTML; /* COPIA TEXTO Y RODEA ETIQUETAS CON separador */ texto1 = texto0.replace(/</g,separador+"<").replace(/>/g,">"+separador); /* CORTA LA COPIA DEL TEXTO SEPARANDO "TAGS" Y "CONTENIDO DE TEXTO" EN ARRAY */ texto1 = texto1.split(separador); numera0(); } function numera0() { /* RECORRE TODOS LOS ELEMENTOS DEL ARRAY DE "TEXTO + TAGS" */ for(b=0; b<texto1.length; b++) { /* SI NO EMPIEZA CON "<" Y TERMINA CON ">" ... */ if(texto1[b].match(/^</) == null && texto1[b].match(/>$/) == null){ /* ... NO ES TAG, Y ENTONCES PONE SUS CARACTERES "ESPACIO" EN UN span */ texto1[b] = texto1[b].replace(/\x20/g,"<span> </span>"); } } /* UNE EL TEXTO SEPARADO EN EL ARRAY Y LO METE EN LUGAR DEL TEXTO ORIGINAL */ hoja.innerHTML = texto1.join(""); numera1(); } function numera1() { var espacios = hoja.getElementsByTagName("span"); /* CUENTA LOS span DEL TEXTO*/ var totEspacios = espacios.length; /* RECORRE UNO A UNO TODOS LOS span DEL TEXTO */ for(s=0; s<totEspacios; s++) { /* SI LA DISTANCIA DE ESTE "span CON ESPACIO" AL TOP ES MAYOR A LA DEL ANTERIOR ...*/ if(espacios[s].offsetTop > altura){ /* ... GUARDA LA NUEVA DISTANCIA EN VARIABLE altura */ altura = espacios[s].offsetTop; /* CREA UN ELEMENTO div ... */ var orden = document.createElement("div"); /* QUE CONTIENE EL NÚMERO DE ORDEN DE LÍNEA numLinea */ var nuevoNum = document.createTextNode(numLinea + "."); /* Y LO INSERTA EN EL div */ orden.appendChild(nuevoNum); /* LE DA UNA CLASE */ orden.setAttribute("class", "linea"); /* HACE AL div "NO-SELECCIONABLE" PARA IEXPLORER */ orden.setAttribute("unselectable", "on"); /* LE ASIGNA LA MISMA DISTANCIA AL TOP QUE LA LÍNEA QUE NUMERA */ orden.style.top = altura +"px"; /* Y LO INSERTA EN LA REGLA PARA LA NUMERACIÓN */ numerado.appendChild(orden); /* SUMA "1" PARA EL SIGUIENTE NÚMERO DE LÍNEA */ numLinea++ } } /* CUANDO TERMINA DE NUMERAR TODO EL TEXTO, REEMPLAZA EL CONTENIDO MARCADO, POR EL TEXTO ORIGINAL */ hoja.innerHTML = texto0; } onload = inicia; </script> <style type="text/css"> body {background-color: silver; color: black; font-size: 18px; font-family: arial, helvetica, sans-serif; } h1 {font-size: 1.6em; } #parrafos {background-color: white; font-size: 1em; padding: 0.5em; margin-left: 2em; position: relative; } #regla {font-size: 1em; position: absolute; left: -2.1em; top: 0.2em; width: 2em; } h2 {font-size: 2.2em; } .linea {position: absolute; font-size: 0.8em; width: 2em; left: 0; top: 0; background-color: black; color: yellow; text-align: right; user-select: none; } acronym {text-decoration: underline; text-underline-position: auto-pos; } </style> </head> <body onresize = "inicia()" /* RECALCULA NÚMEROS DESPUÉS DE UN resize */> <h1>Texto con líneas virtuales numeradas.</h1> <div id="parrafos"> <div id="pagina"> <h2>Latino. </h2> <p>La palabra "latino" para nombrar a los criollos y amerindios es una reducción de "latinoamericano"; y tiene su origen en la <strong>Guerra de Troya</strong>, para terminar en el intento napoleónico de desembarcar en <strong>México</strong> o <strong>Argentina</strong> extendiendo sus conquistas al <em>Nuevo Continente</em>. </p> <p>Cuando <strong>Eneas</strong> (el de <em>La Enéida</em>) regresa con su hijo <strong>Ascanio</strong> del <strong>Asia Menor</strong> hasta <strong>Europa</strong>, conoce a <strong>Lavinia</strong>, hija del rey <strong>Latinio</strong>, y se casa con ella quedándose en su territorio. Allí comienzan a reunirse todos los soldados que vuelven de la guerra, fundando una ciudad llamada <strong>Lacio</strong>, en la actual <strong>Italia</strong>, por <acronym title="Nombre geográfico tomado del de una persona."> eponimia</acronym> con el nombre del suegro de <strong>Eneas</strong>. </p> <p>Sus habitantes fueron los latinos "originales", y formaron parte de los míticos pueblos fundadores de <strong>Roma</strong>, otra ciudad que después se convertiría en un imperio, dominando desde <strong>Italia</strong> hasta <strong>Antioquía</strong> y <strong>Lusitania</strong>. </p> <p>Si bien para el s.XV este imperio ya no existía, su influencia aún se encontraba en la cultura y el idioma que dio origen a las lenguas romances como el francés, rumano, español, portugués o italiano. </p> <p>Cuando los nuevos imperios coloniales conquistaron <strong>América</strong>, trajeron sus idiomas herederos del latín que, exceptuando a algunas colonias inglesas u holandesas, se extendieron por todo el continente. El más difundido es el castellano, que se habla donde hubo colonias españolas (desde <strong>California</strong> hasta la <strong>Tierra del Fuego</strong>) ; le sigue el portugués, que se habla en el <strong>Brasil</strong>; y en mucha menor medida el francés, ya que sus posesiones eran principalmente islas caribeñas. </p> <p>Después de que los ejércitos de <strong>Napoleón</strong> invadieron <strong>España</strong> y <strong>Portugal</strong>, el próximo movimiento a mediano plazo sería hacerse de sus colonias. Pero había una cuestión menor, casi una formalidad ¿cómo llamaría la <strong>Francia Imperial</strong> a sus nuevas tierras?. El nombre más usual era <strong>Hispanoamérica</strong>, porque la mayor parte era española; si le sumamos a <strong>Brasil</strong>, el nombre sería <strong>Iberoamérica</strong>. Pero <strong>Francia</strong> no cabía por ningún lado, así que inventaron el muy creativo nombre de <strong>Latinoamérica</strong>, aprovechando que el francés, al igual que el español y el portugués, son idiomas provenientes del latín. </p> <p>Esta denominación es la que se usa todavía para llamar al subcontinente, y "latinoamericano" —con su forma apocopada "latino"— a sus habitantes. </p> </div> <div id="regla"></div> </div> </body> </html>
El escript reconoce etiquetas, y no pone marcas de span dentro de sus atributos. Pero tiene al menos un bug. Si en una misma línea hay fuentes de 2 alturas distintas, para el escript son 2 líneas distintas.
De momento no se me ocurre cómo arreglarlo. Lo que sí voy a hacer es mejorar la presentación de los números (p.e. que queden sobre el mismo "renglón" y no como un superíndice), porque una utilidad que se me aparece ahora es usarlo en imprimibles.
(Sí, ya sé, las páginas web no son para imprimir, pero ...)
Texto en dos columnas
cuantos lineas de texto tengo en un div?
numeracion de lineas en página