prettyPre, formattare il tag PRE con jQuery e CSS

prettyPre, formattare il tag PRE con jQuery e CSS

Il tag PRE, specialmente se deve contenere del mark-up, può risultare ostico da gestire. In questo tutorial con jQuery e CSS vederemo come mostrare automaticamente il mark-up o il codice presente nel tag rendendo più gradevole alla vista il nostro elemento.

Intro

L’elemento PRE di HTML serve ad indicare un blocco di  “preformatted text”, l’interprete (il browser) userà un font a larghezza fissa e verranno preservati spazi, a capo e tabulazioni. Risulta particolarmente utile per mostrare porzioni di codice ed è possibile anche dare un valore semantico al blocco innestando il tag CODE.

Purtroppo la formattazione di un pezzo di codice o di mark up con PRE non funziona quasi mai come vorremmo. Il problema più comune è l’interpretazione dei tag contenuti in PRE che ci costringe a convertire i simboli nelle rispettive entità, in particolare i segni di maggiore e minore che servono ad aprire e chiudere gli elementi in < e >. Inoltre, risulta fastidioso il mantenimento delle tabulazioni rispetto al documento originale e non all’elemento PRE.

Mark-up interpretato nell'elemento PRE

Mark-up interpretato nell’elemento PRE

Javascript

Facendo qualche ricerca in rete si può trovare una funzione semplice e veloce su StackOverflow, che ripropongo qui con qualche minimo adattamento.

Impostiamo la funzione come plug-in:

(function ( $ ) {
   $.fn.prettyPre = function (){
 (.... qui andrà la funzione..)
 };
}( jQuery ));

Quindi nella funzione iteriamo i tag PRE trovati nella pagina e con la funzione replace() sostituiamo simboli con entità:

var preEl = $(this);
for (var i = 0; i < preEl.length; i++)
  {
   var content = $(preEl[i]).html().replace(/[<>]/g, function(m) { return {'<':'<','>':'>'}[m]});

Calcoliamo il numero di tabulazioni presenti all’inizio del blocco di codice:

   var tabs_to_remove = '';
   while (content.indexOf('\t') == '0')
	{
	tabs_to_remove += '\t';
	content = content.substring(1);
	}

Infine eliminiamo le tabulazioni a inizio di ogni riga:

	var re = new RegExp('\n' + tabs_to_remove, 'g');
	content = content.replace(re, '\n');
	$(preEl[i]).html(content);
	}
  };

La funzione completa appare così:

var preEl = $(this);
for (var i = 0; i < preEl.length; i++)
  {
   var content = $(preEl[i]).html().replace(/[<>]/g, function(m) { return {'<':'<','>':'>'}[m]});
   var tabs_to_remove = '';
   while (content.indexOf('\t') == '0')
	{
	tabs_to_remove += '\t';
	content = content.substring(1);
	}
   var re = new RegExp('\n' + tabs_to_remove, 'g');
   content = content.replace(re, '\n');
   $(preEl[i]).html(content);
  }
};

CSS

A questo punto rendiamo migliore l’aspetto del nostro blocco con CSS.
Creiamo la classe .pretty-pre per formattare il blocco:

.pretty-pre {
	padding-top:20px;
	overflow: hidden;
	width: 70%;
	transition: width 0.9s;
	}

Aggiungiamo una regola molto stretta che introduce un’altra classe: .expand che si deve attivare solo al passaggio del mouse (:hover). Questa regola sgancia il codice dalla pagina ( z-index ) ed espande il PRE con un effetto transition.

Si noti bene che la transition nella classe .pretty-pre (vedi sopra) serve a garantire il rientro quando il puntatore del mouse esce dal blocco.

.pretty-pre.expand:hover {
	position: relative;
	width: 100%;
	z-index: 99;
	transition: width 0.9s;
	}

HTML

Includiamo il CSS nella nostra pagina, salviamo la nostra funzione in un file dal nome prettypre.jquery.js e colleghiamo lo script con un link subito dopo il richiamo a jQuery.

Non resta che aggiungere il trigger al plug-in:

$('.pretty-pre').prettyPre();

Ora un blocco come quello mostrato prima in figura apparirà così:

Mark-up e codice formattati con prettyPre

Mark-up e codice formattati con prettyPre

Conclusioni

Lo script è veloce ed economico in termini di risorse, si adatta sia al mark-up che a piccole porzioni di codice ed è facilmente espandibile la lista delle trasformazioni, visto che è un oggetto passato alla funzione replace. Purtroppo ho riscontrato dei limiti nella gestione del tag <script>, perché facilmente il contenuto verrà interpretato dal browser prima delle trasformazioni, attivando così lo script collegato.

L’intero codice sorgente con una live version sono disponibili su github: