Blame | Last modification | View Log | RSS feed
<?php
/*
* $Id: hightlighter.class.inc,v 1.1 2005-09-22 14:02:49 ddelon Exp $
*
* Souligneur générique pour colorier la syntaxe de langage de programmation
*
* copyrigth Eric Feldstein 2004 mailto:garfield_fr@tiscali.fr
*
* Licence : la meme que wikini(voir le fichier LICENCE).
* Vous êtes libre d'utiliser et de modifier ce code à condition de laisser le copyright
* d'origine. Vous pouvez bien sur vous ajouter à la liste des auteurs.
*
* INSTALLATION : copier le fichier dans le repertoire "formatters" de WikiNi
* UTILISATION : importer la classe dans le script de coloration
* ATTRIBUTS DE LA CLASSE :
* - isCaseSensitiv : booleen - indique si la syntaxe est sensible a la casse
* - comment : array - tableau d'expressions regulieres definissant les commentaires multiligne
* ex : array('({[^$][^}]*})', //commentaires: { ... }
* '(\(\*[^$](.*)\*\))' //commentaires: (* ... *)
* );
* - commentLine : array tableau d'expressions regulieres definissant les commentaires monoligne
* ex : array('(//.*\n)'); //commentaire //
* - commentStyle : string - style CSS inline a utiliser pour la coloration(utilisé dans une
* balise <SPAN style="..."></SPAN>)
* - directive : array - tableau d'expression reguliere pour definir les directive de
* compilation
* - directiveStyle : string - style CSS inline a utiliser pour la coloration
* - string : array - tableau d'expression reguliere pour definir les chaine de caracteres
* - stringStyle : string - style CSS inline a utiliser pour la coloration
* - number : array - tableau d'expression reguliere pour definir les nombres
* - numberStyle : string - style CSS inline a utiliser pour la coloration
* - keywords : array - tableau asociatif contenant des tableaux de liste de mots avec leur style. Ex :
* $oHightlighter->keywords['Liste1']['words'] = array('liste1mot1','liste1mot2','liste1mot3');
* $oHightlighter->keywords['Liste1']['style'] = 'color: red';
* $oHightlighter->keywords['Liste2']['words'] = array('liste2mot1','liste2mot2');
* $oHightlighter->keywords['Liste2']['style'] = 'color: yellow';
* chaque tableau keywords['...'] DOIT posseder les 2 clé 'words' et 'style'.
* - symboles : array - tableau conteant la liste des symboles
* - symbolesStyle : string - style CSS inline a utiliser pour la coloration
* - identifier : array - tableau d'expression reguliere pour definir les identifiants
* - identStyle : string - style CSS inline a utiliser pour la coloration
* METHODE PUBLIQUE DE LA CLASSE :
* - Analyse($text) : $text string Chaine a analyser
* renvoie le texte colorié.
*
* NOTES IMPORTANTES
* - Les expressions reguliere doivent être entre parenthèse capturante pour etre utilisé
* dans une fonction de remplacement. Voir le fichier coloration_delphi.php pour un exemple
* - Lorsque un style est defini à vide, l'expression reguliere n'est pas prise en compte dans
* l'analyse.
* - L'option de recherche est msU : multiligne, le . peut être un \n et la recherche
* est 'not greedy' qui inverse la tendance à la gourmandise des expressions régulières.
*/
class Hightlighter{
//sensibilite majuscule/minuscule
var $isCaseSensitiv = false;
//commentaires
var $comment = array(); //commentaire multiligne
var $commentLine = array(); //commentaire monoligne
var $commentStyle = '';//'color: red';
//directives de compilation
var $directive = array();
var $directiveStyle = '';//'color: green';
//chaine de caracteres
var $string = array();
var $stringStyle = '';
//nombre
var $number = array();
var $numberStyle = '';
//mots clé
var $keywords = array();
//séparateurs
var $symboles = array();
var $symbolesStyle = '';
//identifiant
var $identifier = array();
var $identStyle = '';
//*******************************************************
// Variable privées
//*******************************************************
var $_patOpt = 'msU'; //option de recherche
var $_pattern = ''; //modele complet
var $_commentPattern = ''; //modele des commentaires
var $_directivePattern = '';//modele des directives
var $_numberPattern = ''; //modele des nombres
var $_stringPattern = ''; //modele des chaine de caracteres
var $_keywordPattern = ''; //modele pour le mots cle
var $_symbolesPattern = ''; //modele pour les symbole
var $_separatorPattern = '';//modele pour les sparateurs
var $_identPattern = ''; //modele pour les identifiants
/********************************************************
Methodes de la classe
*********************************************************/
/**
* Renvoie le pattern pour les commentaires
*/
function _getCommentPattern(){
$a = array_merge($this->commentLine,$this->comment);
return implode('|',$a);
}
/**
* Renvoie le pattern pour les directives de compilation
*/
function _getDirectivePattern(){
return implode('|',$this->directive);
}
/**
* Renvoie le pattern pour les chaine de caracteres
*/
function _getStringPattern(){
return implode('|',$this->string);
}
/**
* Renvoie le pattern pour les nombre
*/
function _getNumberPattern(){
return implode('|',$this->number);
}
/**
* Renvoie le pattern pour les mots clé
*/
function _getKeywordPattern(){
$aResult = array();
foreach($this->keywords as $key=>$keyword){
$aResult = array_merge($aResult, $keyword['words']);
$this->keywords[$key]['pattern'] = '\b'.implode('\b|\b',$keyword['words']).'\b';
}
return '\b'.implode('\b|\b',$aResult).'\b';
}
/**
* Renvoie le pattern pour les symboles
*/
function _getSymbolesPattern(){
$a = array();
foreach($this->symboles as $s){
$a[] = preg_quote($s,'`');
}
return implode('|',$a);
}
/**
* Renvoie le pattern pour les identifiants
*/
function _getIdentifierPattern(){
return implode('|',$this->identifier);
}
/**
* Liste des separateur d'apres la liste des symboles
*/
function _getSeparatorPattern(){
$a = array_unique(preg_split('//', implode('',$this->symboles), -1, PREG_SPLIT_NO_EMPTY));
$pattern = '['.preg_quote(implode('',$a),'`').'\s]+';
return $pattern;
}
/**
* Renvoie le modele a utiliser dans l'expression regulière
*
* @return string Modele de l'expression régulière
*/
function _getPattern(){
$this->_separatorPattern = $this->_getSeparatorPattern();
$this->_symbolesPattern = $this->_getSymbolesPattern();
$this->_commentPattern = $this->_getCommentPattern();
$this->_directivePattern = $this->_getDirectivePattern();
$this->_stringPattern = $this->_getStringPattern();
$this->_numberPattern = $this->_getNumberPattern();
$this->_keywordPattern = $this->_getKeywordPattern();
$this->_identPattern = $this->_getIdentifierPattern();
//construction du modele globale en fonction de l'existance d'un style(optimisation)
if($this->commentStyle){ $a[] = $this->_commentPattern; }
if($this->directiveStyle){ $a[] = $this->_directivePattern; }
if($this->stringStyle){ $a[] = $this->_stringPattern; }
if($this->numberStyle){ $a[] = $this->_numberPattern; }
if(count($this->keywords)>0){ $a[] = $this->_keywordPattern; }
if($this->symbolesStyle){ $a[] = $this->_symbolesPattern; }
if($this->identStyle){ $a[] = $this->_identPattern; }
$this->_pattern = implode('|',$a);
return $this->_pattern;
}
/**
* Fonction de remplacement de chaque élement avec leur style.
*/
function replacecallback($match){
$text = $match[0];
$pcreOpt = $this->_patOpt;
$pcreOpt .= ($this->isCaseSensitiv)?'':'i';
//commentaires
if($this->commentStyle){
if (preg_match('`'.$this->_commentPattern."`$pcreOpt",$text,$m)){
return "<span style=\"$this->commentStyle\">".$match[0].'</span>';
}
}
//directive de compilation
if ($this->directiveStyle){
if (preg_match('`'.$this->_directivePattern."`$pcreOpt",$text,$m)){
return "<span style=\"$this->directiveStyle\">".$match[0].'</span>';
}
}
//chaine de caracteres
if ($this->stringStyle){
if (preg_match('`'.$this->_stringPattern."`$pcreOpt",$text,$m)){
return "<span style=\"$this->stringStyle\">".$match[0].'</span>';
}
}
//nombres
if ($this->numberStyle){
if (preg_match('`'.$this->_numberPattern."`$pcreOpt",$text,$m)){
return "<span style=\"$this->numberStyle\">".$match[0].'</span>';
}
}
//mot clé
if (count($this->keywords)>0){
foreach($this->keywords as $key=>$keywords){
if ($keywords['style']){
if(preg_match('`'.$keywords['pattern']."`$pcreOpt",$text,$m)){
return "<span style=\"".$keywords['style']."\">".$match[0].'</span>';
}
}
}
}
//symboles
if ($this->symbolesStyle){
if (preg_match('`'.$this->_symbolesPattern."`$pcreOpt",$text,$m)){
return "<span style=\"$this->symbolesStyle\">".$match[0].'</span>';
}
}
//identifiants
if ($this->identStyle){
if (preg_match('`'.$this->_identPattern."`$pcreOpt",$text,$m)){
return "<span style=\"$this->identStyle\">".$match[0].'</span>';
}
}
return $match[0];
}
/**
* renvois le code colorié
*
* @param $text string Texte a analyser
* @return string texte colorié
*/
function Analyse($text){
$pattern = '`'.$this->_getPattern()."`$this->_patOpt";
if (!$this->isCaseSensitiv){
$pattern .= 'i';
}
$text = preg_replace_callback($pattern,array($this,'replacecallback'),$text);
return $text;
}
} //class Hightlighter
?>