Fonction de coloration syntaxique, highlight pour php, c/c++, pascal

Soyez le premier à donner votre avis sur cette source.

Vue 7 246 fois - Téléchargée 322 fois


Description

Une fonction qui colore vos chaînes à la manière de highlight_string()... toujours intéressant, d'autant qu'elle supporte 3 languages (php,c/c++,delphi)

Je n'ai malheureusement pas eu le temps (ou l'envie) de la commenter, alors j'expose juste le principe : la fonction parcours la chaîne caractère par caractère et en identifie le type (cf les constantes).

Source / Exemple :


<?
/****************************************************/
/* Nom :        coloration.php                      */
/* Auteur :     pgpp05@hotmail.com                  */
/* Créé :       29/11/2003                          */
/* Modifié :    18/05/2004                          */
/****************************************************/
/* Fonction :   Coloration syntaxique d'une chaîne  */
/****************************************************/
/* Entrées :    $str                                */
/*                Chaîne à colorer                  */
/*              $lang                               */
/*                Langage ("php","c","c++","pascal")*/
/****************************************************/

function color($str,$lang)
{
/****************************/
/* DEFINITION DE CONSTANTES */
/****************************/
    $lang=strtolower($lang);

    $wknf=file('./'.str_replace('++','',$lang).'_fncts.txt');

    define("DEF",-1);
    $colorDEF="<font face=Courier size=3 color=#FF0000>";
    $colorERR="<font color=#FF0000>";
    define("SPACE",0);
    //$colorSPACE="<font color=#>";//lol space color !
    define("ID",1);
    $colorID="<font color=#000000>";
    define("NUM",2);
    $colorNUM="<font color=#FF00FF>";
    define("CHAINE",3);
    $colorCHAINE="<font color=#6666FF>";
    define("SCHAINE",4);
    $colorSCHAINE="<font color=#6666CC>";
    define("CECHAP",5);
    $colorCECHAP="<font color=#0000CC><b>";
    define("SYMBOL",6);
    $colorSYMBOL="<font color=#000000><b>";
    define("OP",7);
    $colorOP="<font color=#CC0000>";
    define("PHPVAR",8);
    $colorPHPVAR="<font color=#008800>";
    define("RESERVED",9);
    $colorRESERVED="<font color=#AA0000><b>";
    define("COMPIL",10);
    $colorCOMPIL="<font color=#000000 style=\"background-color: #FF55FF;\"><font color=#0000BB><i>";
    $colorCOMPIL2="</i></font><b>";
    define("POINT",11);
    define("DIESE",12);
    define("WELLKNOWN",13);
    $colorWELLKNOWN="<font color=#000099><b>";

    $colorCOMMENT="<font color=#000000 style=\"background-color: #99FFFF;\">";//"<font color=#559955><i>";

    $fcolor="</i></b></font>";

/****************************/
/* ALGORITHME DE COLORATION */
/****************************/

//echo "STR : ";
    $fin=strlen($str);
    $n=0;$test=0;
    while($n<$fin)
    {
        $car=$str[$n];
        $mot=$car;
        switch(type($car))
        {
            case SPACE:
            {
                while(type($car=$str[++$n])==SPACE) $mot.=$car;
                $cstr.=htmlentities($mot);
                break;
            }
            case ID:
            {
                while(type($car=$str[++$n])==ID or type($car)==NUM) $mot.=$car;
                switch(identifie($mot,$lang)){
                  case ID:{$coul=$colorID;break;}
                  case OP:{$coul=$colorOP;break;}
                  case SYMBOL:{$coul=$colorSYMBOL;break;}
                  case NUM:{$coul=$colorNUM;break;}
                  case RESERVED:{$coul=$colorRESERVED;break;}
                  case WELLKNOWN:{$coul=$colorWELLKNOWN;break;}
                  default:{$coul=$colorDEF;}}
                $cstr.=$coul.htmlentities($mot).$fcolor;
                break;
            }
            case NUM:
            {
                while(type($car=$str[++$n])==NUM || type($car)==POINT) $mot.=$car;
                $cstr.=$colorNUM.htmlentities($mot).$fcolor;
                break;
            }
            case CHAINE:
            {
                if($lang=="pascal" || $lang=="delphi") // le caractère " n'existe pas en pascal
                {
                    $cstr.=$car;
                    $n++;
                    break;
                }
                while(1)
                {
                    $car=substr($str,++$n,1);
                    if(type($car)==CECHAP){$coul=idenctrl($str[$n+1],CHAINE)?$colorCECHAP:$colorERR; $mot.=$coul.htmlentities($str[$n].$str[$n+1]).$fcolor; $n++;} //si c'est un car d'échappement, sauve les 2 car ( du type \* ) et colorise
                    else if($lang=="php" && type($car)==PHPVAR && type($car2=$str[$n+1])==ID){$n++;$mot2=$car.$car2;while(type($car=$str[++$n])==ID or type($car)==NUM)$mot2.=$car;$mot=$mot.$colorPHPVAR.htmlentities($mot2).$fcolor;$n--;} //si c'est une var PHP, colorise à l'intérieur de la chaîne
                    else if(type($car)==CHAINE){$mot.=htmlentities($car);$n++;break;}
                    else $mot.=htmlentities($car);
                    if($n>=$fin){$cstr.=$colorCHAINE.$mot.$fcolor; return($colorDEF.spechar($cstr).$fcolor);}
                }

                $cstr.=$colorCHAINE.$mot.$fcolor;
                break;
            }
            case SCHAINE:
            {
                while(1)
                {
                    $car=$str[++$n];
                    if(type($car)==CECHAP){$coul=idenctrl($str[$n+1],SCHAINE)?$colorCECHAP:$colorERR; $mot.=$coul.htmlentities($str[$n].$str[$n+1]).$fcolor; $n++;} //si c'est un car d'échappement, sauve les 2 car ( du type \* ) et colorise
                    else if(type($car)==SCHAINE){$mot.=htmlentities($car);$n++;break;}
                    else $mot.=$car;
                    if($n>=$fin){$cstr.=$colorCHAINE.htmlentities($mot).$fcolor; return($colorDEF.spechar($cstr).$fcolor);}
                }
                $cstr.=$colorCHAINE.$mot.$fcolor;
                break;
            }
            case POINT:
            case SYMBOL:
            {
                $coul=$colorSYMBOL;$mot="";
                while($n<$fin)
                {
                    if($car=="/") // traite les commentaires
                    {
                        if($str[$n].$str[$n+1]=="//")
                        {
                            $cstr.=$colorSYMBOL.htmlentities($mot).$fcolor; $mot="/";
                            while(($car=$str[++$n])!="\n" && $n<=$fin) $mot.=$car;
                            $coul=$colorCOMMENT;
                            break;
                        }
                        else if($str[$n].$str[$n+1]=="/*")
                        {
                            $cstr.=$colorSYMBOL.htmlentities($mot).$fcolor; $mot="/";
                            while(($car=$str[++$n].$str[$n+1])!="*/" && $n<=$fin) $mot.=$car[0];
                            $mot.="*/";$n+=2;
                            $coul=$colorCOMMENT;
                            break;
                        }
                    }
                    $mot.=$car;
                    $car=$str[++$n];
                    if(type($car)!=SYMBOL or type($car)!=POINT)break;
                }
                $cstr.=$coul.htmlentities($mot).$fcolor;
                break;
            }
            case PHPVAR:
            {
                if($lang=="php")
                {
                    while((type($car=$str[++$n])==ID || type($car)==NUM) && $n<=$fin) $mot.=$car;
                    $cstr.=$colorPHPVAR.htmlentities($mot).$fcolor;
                    break;
                }
                if($lang=="pascal" || $lang=="delphi")
                {
                    $cstr.=$colorNUM.$mot.$fcolor;$n++;
                    break;
                }
            }
            case DIESE:
            {
                if($lang=="c" || $lang=="c++")
                {
                    while(type($car=$str[++$n])==ID && $n<=$fin) $mot.=$car;
                    if(identifie($mot,$lang)==COMPIL)
                    {
                        $cstr.=$colorCOMPIL.htmlentities($mot);//.$fcolor;
                        $mot="";$n--;
                        while(($car=$str[++$n])!="\n" && $n<=$fin) $mot.=$car;
                        $cstr.=$colorCOMPIL2.htmlentities($mot).$fcolor;
                        break;
                    }
                    else
                    {
                        $cstr.=htmlentities($mot);
                        break;
                    }
                }
            }
            default:
            {
                $cstr.=htmlentities($car);
                $n++;
            }
        }
    }
    return($colorDEF.spechar($cstr).$fcolor);
}

/*****************/
/* LES FONCTIONS */
/*****************/

function type($car)
{
    global $lang;
    $o=ord($car);
    if($o==32 or $o==255) return(SPACE); // espace
    if($o>=48 and $o<=57) return(NUM); // [0..9]
    if($o>=65 and $o<=90 or $o>=97 and $o<=122 or $o==95 or $lang=='php' and $o>128) return(ID); // [A..Z] | [a..z] | _ | en php : ord>128
    if($o==34) return(CHAINE); // "
    if($o==39) return(SCHAINE); // '
    if($o==92) return(CECHAP); //     if($o==33 or $o==37 or $o==38 or $o>=40 and $o<=45 or $o==47 or $o>=58 and $o<=64 or $o==91 or $o==93 or $o==94 or $o>=123 and $o<=125) return(SYMBOL); // !%&()*+,-/:;<=>?@[]^{|}
    if($o==36) return(PHPVAR); // $
    if($o==46) return(POINT); // .
    if($o==35) return(DIESE); // #
    return(-1);
}

function identifie($mot,$lang)
{
    $m=strtolower($mot);
    switch($lang)
    {
      case 'php':
        if($m=="div" || $m=="mod") return(SYMBOL);
        if($m=="true" || $m=="false") return(NUM);
        if($m=="and" || $m=="or" || $m=="not") return(SYMBOL); //OP ou SYMBOL ??
        if($m=="function" || $m=="if" || $m=="then" || $m=="else" || $m=="return" || $m=="break" || $m=="for" || $m=="while" || $m=="do" || $m=="switch" || $m=="case" || $m=="global" || $m=="static" || $m=="echo" || $m=="include") return(RESERVED);
        if($m=="bool" || $m=="char" || $m=="double" || $m=="float" || $m=="int" || $m=="long") return(RESERVED);
        //if($m=="print" || $m=="print_r" || $m=="intval" || $m=="header") return(WELLKNOWN);
      break;
      case 'pascal':
      case 'delphi':
        if($m=="div" || $m=="mod" || $m=="enum" || $m=="string" || $m=="array" || $m=="of" || $m=="and" || $m=="not" || $m=="or" || $m=="xor") return(SYMBOL);
        if($m=="true" || $m=="false") return(NUM);
        if($m=="program" || $m=="uses" || $m=="const" || $m=="type" || $m=="var" || $m=="function" || $m=="begin" || $m=="end" || $m=="if" || $m=="then" || $m=="else" || $m=="return" || $m=="break" || $m=="for" || $m=="to" || $m=="while" || $m=="do" || $m=="switch" || $m=="case") return(RESERVED);
      break;
      case 'c++':
        if($m=="allocate" || $m=="__asm" || $m=="__based" || $m=="__cdecl" || $m=="__declspec" || $m=="dllexport" || $m=="dllimport" || $m=="__except" || $m=="__fastcall" || $m=="__finally" || $m=="__inline" || $m=="__int8" || $m=="__int16" || $m=="__int32" || $m=="__int64" || $m=="__leave" || $m=="__multiple_inheritance" || $m=="naked" || $m=="nothrow" || $m=="property" || $m=="selectany" || $m=="__single_inheritance" || $m=="__stdcall" || $m=="thread" || $m=="__try" || $m=="uuid" || $m=="__uuidof" || $m=="__virtual_inheritance") return(RESERVED);
      case 'c':
        if($m=="main" || $m=="bool" || $m=="char" || $m=="double" || $m=="float" || $m=="int" || $m=="long" || $m=="mutable" || $m=="short" || $m=="signed" || $m=="template" || $m=="unsigned" || $m=="virtual" || $m=="void" || $m=="volatile"  ) return(SYMBOL);
        if($m=="true" || $m=="false" || $m=="this") return(NUM);
        if($m=="asm" || $m=="auto" || $m=="bad_cast" || $m=="bad_typeid" || $m=="catch" || $m=="class" || $m=="const" || $m=="const_cast" || $m=="continue" || $m=="delete" || $m=="dynamic_cast" || $m=="enum" || $m=="except" || $m=="explicit" || $m=="extern" || $m=="finally" || $m=="friend" || $m=="goto" || $m=="inline" || $m=="namespace" || $m=="new" || $m=="operator" || $m=="protected" || $m=="register" || $m=="sizeof" || $m=="struct" || $m=="throw" || $m=="try" || $m=="typedef" || $m=="typeid" || $m=="typename" || $m=="union" || $m=="using" || $m=="function" || $m=="if" || $m=="then" || $m=="else" || $m=="return" || $m=="break" || $m=="for" || $m=="while" || $m=="do" || $m=="switch" || $m=="case" || $m=="public" || $m=="private" || $m=="static") return(RESERVED);
        if($m=="#include" || $m=="#if" || $m=="#then" || $m=="#else" || $m=="#elif" || $m=="#endif" || $m=="#ifdef" || $m=="#ifndef" || $m=="#define" || $m=="#undef" || $m=="#error" || $m=="#import" || $m=="#line" || $m=="#pragma") return(COMPIL);
      break;
    }
    //well known functions
    global $wknf;
    $m.="()\r\n";
    $i=0;
    while($fnct=$wknf[$i++]) if($m==$fnct) return(WELLKNOWN);
    return(ID);
}

function idenctrl($ctr,$type)
{
    if($type==CHAINE) return($ctr=='n' || $ctr=='r' || $ctr=='t' || $ctr=='\\' || $ctr=='$' || $ctr=='"');
    if($type==SCHAINE) return($ctr=='\'' || $ctr=='\\');
}

function spechar($str)
{
    $str=str_replace("\t","&nbsp;&nbsp;&nbsp;&nbsp;",$str);
    $str=str_replace("\n","<br>",$str);
    return("<pre>".$str."</pre>");
}
?>

Conclusion :


Pour l'utiliser, il suffit de mettre $cstr=color($str,$lang). Ainsi, $cstr contiendra $str colorisée.
Si vous voulez, vous pouvez la modifier pour permettre simplement le choix des couleurs... bref elle n'est pas optimisée, mais je vous en laisse le soin ;)

PS : attention au temps d'exécution ! Si vous voulez la mettre sur votre site de codes sources, je vous conseille de coloriser le code lorsque l'utilisateur le poste, et d'enregistrer le code colorisé et non le code brut (même si ça prend plus de place).

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
6
Date d'inscription
mardi 14 septembre 2004
Statut
Membre
Dernière intervention
21 juillet 2009

j'ai l'impression que les commentaires ne sont pas gérés ( simple et multi ligne )
Messages postés
2
Date d'inscription
samedi 20 novembre 2004
Statut
Membre
Dernière intervention
30 janvier 2005

Cela vient de moi ou il ajoute un saut de ligne superflu ?

> http://ijones.no-ip.com/v5/index.php?pg=tutos&mode=view&id=5
Messages postés
2
Date d'inscription
samedi 20 novembre 2004
Statut
Membre
Dernière intervention
30 janvier 2005

Merci mec ...
Messages postés
2268
Date d'inscription
mercredi 27 novembre 2002
Statut
Membre
Dernière intervention
13 septembre 2013
3
Salut!
Un truc qui rendrait ta source plus claire est de dresser des tableaux des mots-clés et d'utiliser la fonction in_array

http://www.nexen.net/docs/php/annotee/function.in-array.php

@++

R@f
Messages postés
728
Date d'inscription
jeudi 20 juin 2002
Statut
Membre
Dernière intervention
7 novembre 2007
2
héhé c sympa ça

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.