Foros del Web » Programando para Internet » Javascript »

Líneas virtuales numeradas.

Estas en el tema de Líneas virtuales numeradas. en el foro de Javascript en Foros del Web. Este asunto ya lo habíamos debatido varias veces, pero hasta donde recuerdo nos faltó una versión de "texto con líneas virtuales numeradas". Por "líneas virtuales" ...
  #1 (permalink)  
Antiguo 12/11/2011, 15:12
(Desactivado)
 
Fecha de Ingreso: noviembre-2002
Ubicación: Ciudad Autónoma de Buenos Aires
Mensajes: 2.367
Antigüedad: 21 años, 5 meses
Puntos: 317
Líneas virtuales numeradas.

Este asunto ya lo habíamos debatido varias veces, pero hasta donde recuerdo nos faltó una versión de "texto con líneas virtuales numeradas". Por "líneas virtuales" se entiende a las que se hacen con wrapping o ajuste de línea : si la fuente o la ventana cambian de tamaño, los "renglones" se van a cortar en otra palabra y la cantidad total de líneas va a cambiar.

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> 
Aunque tiene algunos comentarios para el JS, aprovecho el post y los amplío. El modo poco ortodoxo de ubicar la coordenada "y" de cada una de las líneas es "marcar" sus caracteres de espacio y comparar distancias al top del documento desde el primero al último marcados. Cada vez que el offsetTop aumenta sabemos que el texto bajó una línea; y aprovechamos ese valor para posicionar una capa a la izquierda con el número que le corresponda.

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
  #2 (permalink)  
Antiguo 13/11/2011, 07:57
(Desactivado)
 
Fecha de Ingreso: noviembre-2002
Ubicación: Ciudad Autónoma de Buenos Aires
Mensajes: 2.367
Antigüedad: 21 años, 5 meses
Puntos: 317
Respuesta: Líneas virtuales numeradas.

Ésta es una segunda versión. Está toda en una sola función, pero hay otra que permite usar la numeración como botones para "hacer anotaciones al margen" en cada línea.
Por supuesto, se borran al recargar o redimensionar.

También ajusté la posición de los números, para que queden más cerca de la base del texto.

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 2.</title>
<script type="text/javascript">

var hoja, numerado, altura, numLinea, tamano;
var texto0 = "";
var texto1 = [];
var separador = "¥Ñ";
var muneco = "<span class=\"linea\" id=\"dummy\">0</span>";

function numera() {
hoja = document.getElementById("pagina");

numerado = document.getElementById("regla");

numerado.innerHTML = muneco;

tamano = document.getElementById("dummy").offsetHeight;

numLinea = 1;

altura = 0;

texto0 = hoja.innerHTML;

texto1 = texto0.replace(/</g,separador+"<").replace(/>/g,">"+separador);

texto1 = texto1.split(separador);

for(b=0; b<texto1.length; b++) {

if(texto1[b].match(/^</) == null && texto1[b].match(/>$/) == null){
texto1[b] = texto1[b].replace(/\x20/g,"<span> </span>");
}

}

hoja.innerHTML = texto1.join("");

var espacios = hoja.getElementsByTagName("span");

var totEspacios = espacios.length;

for(s=0; s<totEspacios; s++) {

if(espacios[s].offsetTop > altura){
altura = espacios[s].offsetTop;
var orden = document.createElement("div");
var nuevoNum = document.createTextNode(numLinea + ".");
orden.appendChild(nuevoNum);
orden.setAttribute("class", "linea");
orden.setAttribute("onclick", "senalador(this)");
orden.setAttribute("unselectable", "on");
orden.style.top = altura + espacios[s].offsetHeight - tamano +"px";
numerado.appendChild(orden);
numLinea++
}

}

hoja.innerHTML = texto0;

}

function senalador(T) {
T.style.backgroundColor = "blue";

var descripcion = 
prompt("Escriba una descripción para esta línea.", T.title);
 
if(descripcion) {
T.title = descripcion;
T.style.backgroundColor = "red";
}

else {
T.title = "";
T.style.backgroundColor = "";
}

}

onload = numera;
</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.6em; width: 2em; left: 0; 
top: 0; background-color: black; color: yellow; text-align: right; 
user-select: none; cursor: pointer; }

acronym {text-decoration: underline; cursor: help; 
text-underline-position: auto-pos; }

#dummy {visibility: hidden; }

.derecha {text-align: right; font: 0.6em cursive;}
</style>

</head>

<body onresize = "numera()">

<h1>Texto con líneas virtuales numeradas.</h1>

<div id="parrafos">

<div id="pagina">
<h2>El caracter "&". </h2>

<p>Fue —y aún es— una contracción estenográfica. Su nombre es "Et", 
y su origen se remonta a la <b>Roma </b>precristiana. </p>

<p>Como escribir libros a mano da mucho trabajo, algunos copistas 
usaban 'dibujos' que representaban palabras o sílabas de uso común. 
"Et" en latín es una conjunción copulativa, como la "y" o la "e" en 
nuestro idioma; al unir la "E" y la "T" en un sólo trazo, quedó como 
un signo en sí mismo, pero con igual valor y pronunciación. </p>

<p>Cuando lo usamos fuera del latín se puede pronunciar según el 
idioma local (<b>Tompson & Williams</b> : "tomson y uíliams") o 
mantener la pronunciación del idioma original de las otras palabras 
(<b>Bony & Clide </b>: "boni and claid"). </p>

<p>Tambien se la conoce como "i comercial", pero quien le puso ese 
nombre no sólo estaba demostrando su escasa cultura general (la debe 
haber visto nada más que en marcas comerciales) sino también sus 
pocas ganas de investigar y <i>garrar </i>el mataburros. </p>

<p>El caracter se utiliza como operador lógico y matemático, además 
de componer otras abreviaturas; como "etcétera", del latín "<i>et 
cetera</i>" ("et quetera") que significa "y siguientes", y se abrevia 
"&c.". </p>

<p>La grafía fue evolucionando con los siglos, pero todavía hay 
algunas fuentes que usan su versión más arcáica, donde podemos 
distinguir claramente las formas de la "E" y de la "T". </p>

<center><img src="http://img847.imageshack.us/img847/4136/ets.jpg"></center>

<p class="derecha">(Extraído de un tema publicado en <i>Foro-
Virtual</i>. <br>
Imagen en <a href="http://imageshack.us/photo/my-images/847/ets.jpg/">
http://imageshack.us/photo/my-images/847/ets.jpg/</a>. ) 

</p>
</div>

<div id="regla"></div>

</div>

</body>
</html> 

Etiquetas: html, js, virtuales
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 12:54.