
Geshi - obarvovátko kódu, vlastní filtr
26. Ledna 2010
Pokud se vám líbí "obarvovače" kódu, tak pravděpodobně nejlepší volbou pro PHP je knihovna Geshi. Možná ale narazíte na problém, Když budete mít dlouhý text a mezi ním vložený kód k "obarvení". Budete potřebovat nějaký parser. Dnes si jeden takový parser ke Geshi Syntax Highlighteru napíšeme.
Dnes bude víc kódu a méně textu. Předpokládejme, že váš kód bude uložen mezi znaky <pre></pre> s atributy lang="" a lines="" (další atributy si můžete snadno dopsat).
Nejdříve napíšeme třídu a řídící metodu.
require_once 'geshi/geshi.php'; /* * Geshi Filter * * @author Dominik Vesely <vesely@dominoo.cz> * */ class Dominoo_GeshiFilter { /* * Hlavni funkce cele tridy * @param $text Text * @return Text vcetne syntax coloringu */ static function generateGeshi($text) { if (ini_get('pcre.backtrack_limit') < 1000000) { ini_set('pcre.backtrack_limit', '1000000'); } if (strpos ( $text, 'pre>' ) === false) { return $text; } $regex = "#<pre \s*(.*?)>(.*?)</pre>#s"; $text = preg_replace_callback ( $regex, array ('self', 'match' ), $text ); return $text; }
Nejdříve musíme zajistit aby nám funkce nepřestala obarvovat bez upozornění. Zvětšením backtrack_limitu bychom tomu měli zabránit. Pokud by byl text příliš dlouhý a limit byl nastaven na nízkou hodnotu skončilo by parsování v půlce a funkce by o tom nedala žádnou zprávu. Pokud celý text neobsahuje pre>, znamená to, že text neobsahuje kód a vrátíme ho. Pokud text splňuje přesné požadavky zavoláme funkci preg_replace_callback, která pro každý výskyt spustí funkci match s parametrem $text.
/* * Callback funkce ktera vytvori geshi objekt a vygeneruje kod * @param $matches * @return unknown_type */ public function match(&$matches) { $args = Dominoo_GeshiFilter::parseAttribs ( $matches [1] ); $text = $matches [2]; $lang = $args ["lang"]; $lines = $args ["lines"]; // $start = $args["start"]; // k entitam doplnte stredniky problem s generovanim kodu $html_entities_match = array ("|\|", "#<#", "#>#", "|'|", '#"#', '# #', '#&#' ); $html_entities_replace = array ("\n", '<', '>', "'", '"', ' ', '&' ); // k entitam doplnte stredniky problem s generovanim kodu $text = preg_replace ( $html_entities_match, $html_entities_replace, $text ); $text = str_replace ( '<', '<', $text ); $text = str_replace ( '>', '>', $text ); $text = str_replace ( "\t", ' ', $text ); $geshi = new GeSHi ( $text, $lang ); $geshi->enable_line_numbers ( (($lines == "fancy") ? GESHI_FANCY_LINE_NUMBERS : GESHI_NORMAL_LINE_NUMBERS) ); $geshi->enable_keyword_links ( false ); if($lines == "none") { $geshi->enable_line_numbers(GESHI_NO_LINE_NUMBERS); } $geshi->enable_classes (); $text = $geshi->parse_code (); return $text; }
Tato funkce zajišťuje vygenerování obarveného kódu. Nejdříve změníme některé znaky na entity a naopak. Vygenerujeme Geshi kód a pokud máme nastaven argument lines na none, tak zrušíme číslování řádek. Poslední věc kterou musíme udělat je napsat funkci která nám parsuje argumenty.
/* * Funkce ktera vraci pole atribut => hodnota * @param $attribs String attributu * @return pole attributu */ static function parseAttribs($attribs) { $attr = explode(" ", $attribs ); $attributes = array (); foreach ( $attr as $attribute ) { $a = explode ( "=", $attribute ); $regex = '/\"(.*)\"/'; preg_match( $regex, $a[1], $m ); $attributes[$a[0]] = $m[1]; } return $attributes; } }
Funkce rozdělí atributy podle mezer a vrátí pole ve tvaru attribut => hodnota. A to je celé. Takto napsaný filtr bude fungovat na vaše kódy, které jsou obaleny textem. Doufám, že se vám filter bude hodit, nebo si ho upravíte podle svých potřeb.
Ohodnoť článek
Ohodnoťte článek.
|
- Zobrazeno 935x
- 0 komentářů
- Přidat na del.icio.us
- Sdílet na Facebooku







Přidat příspěvěk