Syntax Highlight con HTML Purifier y GeSHi

En Syntax Highlighting and Allowing HTML in Comments, Jay Pipes nos explica cómo han utilizado las librerias PHP HTMLPurifier de Edward Yang y GeSHi de Nigel McNie para crear la funcionalidad de Sytax Highlight en el nuevo MySQL Forge.

Además nos facilitan las dos elegantes funciones ( clean_and_codify y syntax_highlight ) que han acabado utilizando en "vivo":

PHP:
  1. /**
  2.    * Highlights the text as code in the supplied language
  3.    *
  4.    * @return  string    The marked up code
  5.    * @param    subject    The text to markup
  6.    * @param    language  The language to use for highlighting
  7.    */
  8.   public static function syntax_highlight($subject, $language) {
  9.     /* Format the code with GeSHi */
  10.     include_once(APP_DIR . '/opt/geshi/geshi.php');
  11.     $geshi= new GeSHi($subject, $language);
  12.     $geshi->enable_classes();
  13.     $geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS);
  14.     return $geshi->parse_code();
  15.   }
  16.  
  17.   /**
  18.    * Returns a cleaned and syntax-highlighted string of HTML
  19.    *
  20.    * @return  string    Cleaned and codified text
  21.    * @param    subject    The text to cut into code pieces
  22.    */
  23.   public static function clean_and_codify($subject) {
  24.     $original= $subject;
  25.     $code_pieces= array();
  26.     $code_regex= '/[\[\<]code\s*(lang|language)\=[\"\'](\w+)[\"\'][\]\>]([\D\S]+?)[\[\<]\/code[\]\>]/';
  27.     $code_delimiter= "CODECODECODE";
  28.  
  29.     /* First split the text into code and non-code blocks */
  30.     while (preg_match($code_regex, $subject, $code_matches) == 1) {
  31.       $language= trim(strtolower($code_matches[2])); // 0-index is the full match
  32.       $code_sample= $code_matches[3];
  33.       $entire_code_string= $code_matches[0];
  34.       $code_sample= str_replace("\t", "  ", $code_sample); /* Replace tabs with spaces */
  35.       $code_pieces[]= array('lang'=>$language
  36.                           , 'text'=>$code_sample);
  37.       $subject= str_replace($entire_code_string, $code_delimiter, $subject);
  38.       $code_matches= array(); //reset
  39.     }
  40.  
  41.     /*
  42.      * Assume two consecutive newlines are a paragraph.
  43.      */
  44.     /* Normalize Newlines */
  45.     $subject = str_replace("\r\n", "\n", $subject);
  46.     $subject = str_replace("\r", "\n", $subject);
  47.     $subject = preg_replace("/[\n]{2}/", "<p>", $subject);
  48.  
  49.     /*
  50.      * Next, do the same thing with markup sections
  51.      * We use HTMLPurifier here for safe checks with some allowed
  52.      * tags for ease of use
  53.      */
  54.     include_once(APP_DIR . '/opt/htmlpurifier/library/HTMLPurifier.auto.php');
  55.     $config = HTMLPurifier_Config::createDefault();
  56.     $config->set('HTML', 'Doctype', 'XHTML 1.0 Transitional');
  57.     $config->set('HTML', 'AllowedElements', 'a,em,blockquote,p,code,pre,strong,b');
  58.     $config->set('HTML', 'AllowedAttributes', 'a.href,a.title');
  59.     $config->set('HTML', 'TidyLevel', 'light'); // should be enough since we don't allow many elements.  this really just cleans up dangling elements...
  60.     $purifier= new HTMLPurifier();
  61.     $subject= $purifier->purify($subject, $config);
  62.  
  63.     /*
  64.      * Now $subject should contain CleanMarkup\n|||CODE|||\nCleanMarkup...
  65.      * We now replace the code sections by passing an executable string
  66.      * to the regex parser (the /e option) and using the syntax_highlight
  67.      * function to do the grunt work
  68.      */
  69.     $num_code_pieces= count($code_pieces);
  70.     $i= 0;
  71.     if ($num_code_pieces> 0) {
  72.       $replacement= "TextDecorator::syntax_highlight(trim(\$code_pieces[\$i]['text'], \"\r\n \"), \$code_pieces[\$i++]['lang']);";
  73.       $subject= preg_replace('/' . $code_delimiter . '/e', $replacement, $subject);
  74.     }
  75.     return $subject;
  76.   }

Términos relacionados:

Deja tu opinión

Sólo se permiten las etiquetas XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Post anteriores/siguientes:

Post (quizás) relacionados:

  • Efectos con imágenes y CSS

  • Varios enlaces relacionados con el tema: Caótico Neutral: Rollovers con CSS Programación.com: Menú de imágenes con CSS Afficher Masquer des calques sans javascript Affiche-image Cool CSS Image Pop-up Remote Rollovers CollyLogic Scroll-Fade Moryson.net...
  • Preload con CSS, sin Javascript

  • En el trabajo me he encontrado con el caso de tener que realizar un pequeño snippet que requiere dos cosas básicas: Precarga de unas 30 imágenes Funcionalidad...
  • De re varia

  • Interesante proyecto de páginas de inicio utilizando AJAX Servicio de publicación de libros. También puedes crear tus propios sellos en este otro sitio web. Servicio similar a...
  • Limitar Descarga o Apertura de ficheros en Internet Explorer

  • Sólo válido para IE 6 SP2 y posteriores, (aunque hay formas de lograr lo mismo del lado del servidor utilizando, por ejemplo un header content...
  • Yo centro, tu centras, el centra

  • Centrar con CSS... cómo definirlo ? Es ... tan... mmmm... como lo diria ? ... ¿COÑAZO? Centrar Horizontalmente: W3C: Centrar líneas de texto W3C: Centrar un bloque Andy...