Resaltando la sintáxis de códigos en WordPress

Hasta ahora no he encontrado una solución para resaltar la sintáxis de segmentos de código en WordPress.  Hasta la fecha he utilizado varios plugins con resultados parcialmente exitosos.

El primero que probé fue CodeHighlighterPlugin de IdeaThinking.com.  Es simple, resalta la sintáxis de múltiples lenguajes y opcionalmente permite mostrar un número de línea.  Para señalar el código a resaltar se debe encerrar entre etiquetas <pre lang=”XXXX” lineno=”1″>…</pre>.

Después encontré a varios blogs que resaltaban el código de manera mas elegante, con segmentos que coloreaban las líneas y permitían cambiar entre vista enrriquecida y vista plana así como copiar al portapapeles.  Encontré entonces al Google Syntax Highlighter for WordPress de Peter Ryan.  Soporta menos lenguajes (no incluye a bash por ejemplo) sin embargo es mi favorito hasta el momento.  Para segmentar el código a resaltar se debe encerrar entre etiquetas <pre name=”code” class=”XXXX”>…</pre>.

El problema hasta ahora es que TinyMCE, el editor WYSIWYG de WordPress, es felíz borrándome los atributos de los pre convirtiéndo mis fragmentos de código en invisibles para el resaltador haciendo que cada vez que edite o cree un artículo con códigos tenga que editar los textos de manera visual y después tenga que corregir las etiquetas de manera HTML.  Es infame!

Buscando una mejor opción ante este problema encontré el plugin SyntaxHighlighter2 de S H Mohanjith el cual hábilmente utiliza una sintaxis BBCode para segmentar el código a resaltar:  [source language=’XXXX’]…[/source].

Sin embargo le encontré un problema colateral al plugin: al no utilizar etiquetas pre, el editor/navegador no respetan los espacios en blanco que contenga el código a su izquierda, es decir, se ignora la identación.  El autor muy amablemente me sugirió copiar y pegar los códigos desde el modo HTML sin embargo esto es lo que precisamente quiero evitar.

Anoche, ante la imposibilidad de encontrar una mejor solución y mi testarudez, tuve una idea: utilizar el plugin de Peter Ryan el cual no funciona como quisiera porque el editor le remueve el atributo name y agregárselo de manera dinámica cuando cuando la página se ha desplegado en el cliente.

Hoy me dí manos a la obra y encontré que WordPress utiliza jQuery así que investigué como manipular el evento onLoad, obtener todas las etiquetas pre y como agregarles el atributo name=’code’ faltante.  El siguiente fue el resultado.

<script type='text/javascript'>
jQuery(document).ready(function() {
    jQuery('pre').each(function () {
         jQuery(this).attr('name', 'code');
    });
});
</script>

Por razones aún desconocidas no pude hacer funcionar el plugin en el onLoad también para que se encolaran los códigos y terminaran ejecutándose secuencialemente cuando el árbol DOM estuviera listo.  Como alternativa modifiqué apropiadamente el archivo fuente del plugin que inserta el script en la página del blog.

En wp-content/plugins/google-syntax-highlighter/google_syntax_highlighter.php agregué las siguientes líneas al final del código.

<script class="javascript">
/* sección de código agregada */
jQuery('pre').each(function () {
        jQuery(this).attr('name', 'code');
});

/* código ya existente en el archivo */
dp.SyntaxHighlighter.ClipboardSwf = '<?php echo $current_path; ?>Scripts/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');
</script>

Aún tengo que utilizar el módo HTML o utilizar el botón Insert/Edit Attributes de TinyMCE para indicarle a las etiquetas pre cual es el lenguaje de su contenido (class), sin embargo ya no tengo que preocuparme por el atributo name ni porque este sea borrado cada vez que edite al artículo.

Enlaces.

2 thoughts on “Resaltando la sintáxis de códigos en WordPress”

  1. Para que este ‘hack’ funcione es necesario que el tema cierre el ‘footer’ correctamente, es decir, deberá incluír la siguiente instrucción justo antes de cerrar el BODY y el HTML.

    < ?php wp_footer(); ?>
    
  2. Si por alguna extraña razón WordPress no está utilizando jQuery sino Prototype, como es mi caso en este momento, reemplace el siguiente código jQuery:

    jQuery('pre').each(function () {
            jQuery(this).attr('name', 'code');
    });
    

    Con el siguiente código Prototype.

    $$('pre').each(function (element, index) {
            element.writeAttribute('name', 'code');
    });
    

Leave a Reply

Your email address will not be published. Required fields are marked *