Cómo añadir números de linea a los bloques de código
2004-11-29 19:56:46
Acabo de descubrir cómo añadir números de linea a los bloques de código que están dentro de texto preformateado. Se trata de usar una función javascript que recoge todos los elementos pre, y llama a una expresión regular que devuelve el número de lineas en ese bloque. Entonces, usando innerHTML simplemente añadimos una capa div que contiene los números de linea y se le da estilo usando CSS. El javascript, que forma parte de un espacio propio (un objeto literal para encapsular sus funciones) sería algo del estilo:
// adds line numbers to code sections:
numberCodeTags : function(){
var PRE = document.getElementsByTagName('pre');
var nl = /\n+/mg;
for (var i = 0; i < PRE.length; i++) {
var t = PRE[i].innerHTML;
//mozilla/ff cannot select all lines of a code element
//that is inside a pre element:
if(document.addEventListener && !window.opera) {
Extras.getCodeText(PRE[i]);
}
//will only work in mozilla+op (IE replaces \n by a space so its useless):
var NL = Extras.getMatchArray(t,nl);
if(NL) {
var numeros = "";
for (var lineas = 1; lineas < NL; lineas++)
numeros += lineas +"\n";
PRE[i].innerHTML += "<div class='lines'>"+numeros+"</div>";
}
}
},
// matches a regexp to a string, returns array
getMatchArray : function(myString,myRegExp){
return myString.match(myRegExp).length;
},
// FF hack to make easier select all lines of a
//code element that is inside a pre element:
getCodeText : function(obj){
var color = CSS.getStyle(obj.firstChild,"color");
var bgcolor = CSS.getStyle(obj.firstChild,"backgroundColor");
if(bgcolor=="transparent") bgcolor="white";
obj.onmouseover = function(){
obj.firstChild.style.color = bgcolor;
obj.firstChild.style.backgroundColor = color;
}
obj.onmouseout = function(){
obj.firstChild.style.color = color;
obj.firstChild.style.backgroundColor = bgcolor;
}
},
El CSS podría ser algo parecido a estas lineas:
pre {
position: relative;
color: #913117;
padding: 0px 1em 0px 1em;
margin: 0px;
font-family: Courier, monospace;
font-size: 1em;
}
code {
font-variant: normal;
color: #913117;
}
pre code {
position: relative;
top: 0px;
left: 1.2em;
font-variant: normal;
color: #913117;
padding: 0px;
margin: 0px;
}
pre .lines {
position: absolute;
top: 1em;
left: 0px;
width: 1.2em;
padding: 0px;
margin: 0px 1.2em 0px 0px;
background: #913117;
color: white;
}
La técnica parece funcionar solamente en Mozilla y Opera. IE reemplazaba los saltos de linea por espacios así que lo he ignorado. Los demás navegadores degradan tranquilamente.
Como ya han comentado, en Mozilla hay un fallo que no permite la selección de bloques de código que están dentro de bloques de texto preformateado. He intentado añadir un fondo de color (solamente para Mozilla) al pasar el ratón por encima, porque así parece un poco más fácil de ver cómo poder seleccionar. Aparentemente, si empezamos la selección en el espacio que hay entre el texto preformateado y el bloque de código (el espacio en blanco entre los números y el código), se deja seleccionar.