Igor Kulman

Automatické zvýrazňovanie zdrojových kódov v texte

· Igor Kulman

Keďže z času na čas uvádzam v texte aj rôzne zdrojové kódy, napadlo ma vymyslieť funkciu, ktorá tieto zdrojové kódy v texte článku našla a zvýraznila, nech je celý článok prehľadnejší.

Knižníc na zvýrazňovanie zdrojových kódov je viacero, ja som a rozhodol pre GeSHi kvôli jednoduchému použitiu a podpore veľkého množstva jazykov.

Všetky zdrojové kódy v článkoch má uzavreté medzi <div class="vypis"> a </div>, najzložitejšou časťou teda bolo vymyslieť callback funkciu, ktorá by v texte tieto úseky našla a nahradila ich výstupom z GeSHi.

GeSHi musí pri zvýrazňovaní vedieť o aký jazyk ide, aby mohol kód správne zvýrazniť. Rozhodol som sa preto zmeniť uzatváranie kódu na <div class=”vypis-jazyk”< a </div< a <div class=”vypis”< a </div<, kde prvá varianta bude znamenať explicitne určený jazyk, ktorý ma GeSHi použiť pri zvýrazňovaní a pri druhej variante sa použije zvýrazňovanie pre PHP, ktorého kódy uvádzam najčastejšie.

Na náhradu textu stačí použiť už len správny regulárny výraz

content["text"] = preg_replace_callback('/\<div class="vypis[\-]{0,1}([^"]*)">(.*?)\<\/div>/s', "highlightCode", $content["text"]);
  funkciu na samotné nahradenie textu

function highlightCode($in) {
  $text = $in[2]; 
  if (empty($in[1])) //nebol zadaný jazyk
    $lang = "php"; // predvolené je php
  else
    $lang = $in[1]; 
    $text = trim($text);
    $text = strip_tags($text); //odstránenie html značiek
    $text = html_entity_decode($text); //prevod z entít na značky
    $geshi =& new GeSHi($text, $lang);
    $geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS); 
  return $geshi->parse_code();
}

Regulárny výraz namatchuje zadaný text a vráti pole s 3 položkami; celým textom, zadaným jazykom ($in[1]) a samotným zdrojovým kódom ($in[2]).

Zdrojové kódy mám v článkoch zakódované pomocou html entít, z textu treba teda najprv odstrániť všetky html značky, ktoré udávajú formátovanie a netýkajú sa samotného kódu (br,p …). Následné sú html entity prevedené naspäť na html značky (vyžaduje to GeSHi) a je vrátený zvýraznený text.