Formatear el código como en Sentido Web
17:00 H (CET)| Temas: Javascript
Para aquellos que les guste como formateamos los comentarios en Sentido Web, vamos a explicar el código creado por Choan:
El proceso que sigue es el siguiente:
- Obtener todos los elementos pre.
- Para cada pre leer el primer elemento code que tenga.
- Obtenemos el texto que contiene.
- Dividimos el texto en líneas.
- Por cada línea comprobamos si hay algun tipo de comentario, si hay comentario lo separamos en dos partes para luego darle distintos estilos, diferenciando así el formato del comentario.
- Nos creamos un elemento ol, y en cada li insertamos una línea obtenida anteriormente.
- Sustituimos el elemento pre por el ol.
Destripemos un poco el código:
Primero obtenemos las etiquetas pre, comprobando primero si se puede ejecutar este script (si existe el método getElementsByTagName)
function lipt() {
/* change to FALSE if you don't want to proccess comments (boogie buggy) */
var PROCCESS_COMMENTS = true;
if (!document.getElementsByTagName) {
return;
}
var ns = document.getElementsByTagName('html')[0].getAttribute('xmlns');
// look for pre tags in the doc
var pres = document.getElementsByTagName('pre');
if (0 == pres.length) {
return; // no pre tags, nothing to do
}
Por cada pre, obtenemos el primer elemento code que tenga y obtenemos el texto que contiene.
for (var i = 0; i < pres.length; i++) {
var pre = pres[i];
// search for the first code element inside the pre
var code = pre.getElementsByTagName('code')[0];
if (null == code) {
continue; // no one here, try with the next pre tag
}
// go for the job
var inMultiLineComment = false;
var inHtmlComment = false;
var content = getText(code);
Se normalizan las saltos de línea (solo habrá \n y no otro tipo de codificación) y obtenemos las líneas para tratarlas individualmente.
// normalize new lines
if (!window.opera) { /* Opera seems to have a nice bug with global replacements */
content = content.replace(/\n|\r|\r\n/g, '\n');
} else {
content = content.replace(/\n|\r|\r\n/, '\n');
}
content = content.replace(/^\n*/, ''); /* trim empty lines at start */
content = content.replace(/\n*$/, ''); /* trim empty lines at the end */
var lines = content.split('\n');
Ya tenemos las líneas, ahora comprobamos si tiene comentarios, empezamos sustituyendo los tabuladores por cuatro espacios y contando cuantos espacios hay para diferenciando la profundidad en la tabulación con distintos estilos (que veremos más tarde).
var ol = createElement('ol', ns);
ol.className = 'code';
for (var j = 0; j < lines.length; j++) {
var line = lines[j];
line = line.replace(/\t/g, ' '); // replace tab with four spaces
var cname = 'tab' + (Math.floor(countSpaces(line) / 4)); // className for this line
var restSpaces = countSpaces(line) % 4;
line = line.replace(/^ +/, '');
if (restSpaces) {
for (var k = 0; k < restSpaces; k++) {
line = '\u00A0' + line; /* equivalent in Unicode */
}
}
Empezamos a tratar las líneas comprobando si hay comentarios.
if (inMultiLineComment || inHtmlComment) {
parts = ['', line];
} else {
parts = [line];
}
if (PROCCESS_COMMENTS) {
var slashSlashPos = line.indexOf('//');
var starSlashPos = line.indexOf('/*');
var slashStarPos = line.indexOf('*/');
var htmlCmtStart = line.indexOf('');
Hora de los comentarios, miramos cada tipo de comentarios y tenemos cuidado de que no se encuentren entre comillas u otros casos que invalide el comentario (por ejemplo http://, // no se trata de un comentario).
labelSlashSlash: if (slashSlashPos != -1) {
switch (line.charAt(slashSlashPos -1)) {
case '"':
case "'":
case ':': /* don't process URIs as comments */
break labelSlashSlash;
}
//parts = line.split('//');
//parts[1] = '//' + parts[1];
parts[0] = line.substring(0, slashSlashPos);
parts[1] = line.substring(slashSlashPos)
} else if (starSlashPos != -1) {
switch (line.charAt(starSlashPos -1)) {
case '"':
case "'":
break labelSlashSlash;
}
if (!inMultiLineComment) {
parts = line.split('/*');
parts[1] = '/*' + parts[1];
}
inMultiLineComment = true;
}
labelHtmlCmt: if (htmlCmtStart != -1) {
switch (line.charAt(htmlCmtStart -1)) {
case '"':
case "'":
break labelHtmlCmt;
}
if (!inHtmlComment) {
parts = line.split('
Feedback (4) » Formulario
1. Choan ~ Martes, 25 Abr 2006 | 11:22H:
Pues me siento la mar de conforme, Luis, lo has explicado de maravilla (aunque se podrían comentar algunas cosillas más). Lo que te has dejado en el tintero es mi artículo original, LIPT: Inyección de listas a gogó.
Por cierto, hacía tiempo que no le echaba un ojo a ese código y, demonios, no está mal, aunque si lo escribiera de nuevo a día de hoy, sería bien distinto.
Salud.

