Changeset 60666 in spip-zone for _plugins_/coloration_code


Ignore:
Timestamp:
Apr 25, 2012, 10:11:18 PM (8 years ago)
Author:
marcimat@…
Message:

Les expressions régulières, c'est d'un complexe !

Alors, au programme du colorieur SPIP par défaut

  • on corrige la recherche de critères de boucle lorsqu'ils ont les accolades à l'intérieur
  • on permet de colorer différemment les critères et les paramètres de balises ou filtres, et cela en echappant les accolades des critères le temps de chercher les paramètres. On ajoute pour ce faire un petit hack dans Geshi pour indiquer que l'on peut utiliser une fonction de callback différente de la sienne. Cette fonction doit retourner un code préparé comme geshi attend, évidemment.
Location:
_plugins_/coloration_code/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/coloration_code/trunk/geshi/geshi/spip2.php

    r60585 r60666  
    3636
    3737// criteres | arguments : {critere > 0} {critere = #ENV{truc}}
    38 @define('REG_CRITERES', '\{(\s*(?:([^{}]+)|(?R))*\s*)\}');
    39 // la meme chose sans etre capturant
    40 #@define('REG_CRITERES_TOUT', '\{(?:\s*(?:(?:[^{}]+)|(?R))*\s*)\}');
    41 @define('REG_CRITERES_TOUT', '\{(?:\s*(?:(?>[^{}]+)|(?R))*\s*)\}');
     38@define('REG_CRITERES',           '\{(?:\s*(?:(?>[^{}]+)|(?R))*\s*)\}');
     39// la meme chose sans rien de capturant
     40@define('REG_CRITERES_TOUT',      '\{(?:\s*(?:(?>[^{}]+)|(?R))*\s*)\}');
     41// la meme chose en capturant {, contenu et } en 3 morceaux
     42@define('REG_CRITERES_ACCOLADES', '(\{)(\s*(?:(?>[^{}]+)|(?R))*\s*)(\})');
    4243
    4344// Remplacements de Regexp par GESHI
     
    6364// 4) trouver les criteres
    6465
     66
     67// Aide pour les reg de boucle
     68// ?R est applique sur l'expression complete.
     69// on indique donc la parenthese que l'on souhaite avec ?x
     70// sinon ca ne fonctionne pas (des qu'un critere a d'autres accolades internes.)
     71@define('REG_CRITERES_BOUCLE', '(?:(\s*' . REG_CRITERES . '\s*)*)'); // 1 parenthese capturante pour la recursion
     72
    6573// 1) <BOUCLEx(TABLE){criteres} /> ( la fin /> )
    6674@define('REG_BOUCLE_FIN', '((?:' . REG_DEBUT_BOUCLE . ')(?:' . REG_NOM_TABLE_BOUCLE . ')'
    6775        // criteres + fin de boucle
    68         . '(?:(?:\s*' . REG_CRITERES . '\s*)*))(' . REG_FIN_BOUCLE . ')');
     76        . str_replace('?R', '?2', REG_CRITERES_BOUCLE) . ')(' . REG_FIN_BOUCLE . ')');
    6977
    7078// 2) <BOUCLEx(TABLE){criteres} @@/>@@ ( le debut <BOUCLEx )
    7179@define('REG_BOUCLE_DEBUT','(' . REG_DEBUT_BOUCLE . ')((?:' . REG_NOM_TABLE_BOUCLE . ')'
    7280        // criteres + fin de boucle
    73         . '(?:(?:\s*' . REG_CRITERES . '\s*)*)(?:' . REG_FIN_BOUCLE_TROUVE . '))');
     81        . str_replace('?R', '?3', REG_CRITERES_BOUCLE) . '(?:' . REG_FIN_BOUCLE_TROUVE . '))');
    7482
    7583// 3) @@<BOUCLEx@@ (TABLE){criteres} @@/>@@ ( la table (TABLE) )
    76 @define('REG_BOUCLE_TABLE','(' . REG_DEBUT_BOUCLE_TROUVE . ')(' . REG_NOM_TABLE_BOUCLE . ')'
     84@define('REG_BOUCLE_TABLE','(' . REG_DEBUT_BOUCLE_TROUVE . ')(' . REG_NOM_TABLE_BOUCLE . ')' . '('
    7785        // criteres + fin de boucle
    78         . '((?:(?:\s*' . REG_CRITERES . '\s*)*)(?:' . REG_FIN_BOUCLE_TROUVE . '))');
     86        .  str_replace('?R', '?4', REG_CRITERES_BOUCLE) . '(?:' . REG_FIN_BOUCLE_TROUVE . '))');
    7987
    8088// 4) @@<BOUCLEx@@ @@(TABLE)@@ {criteres} @@/>@@ ( des criteres {criteres} )
    8189@define('REG_BOUCLE_CRITERES','((?:' . REG_DEBUT_BOUCLE_TROUVE . ')(?:' . REG_TABLE_BOUCLE_TROUVE . '))'
    8290        // criteres + fin de boucle
    83         . '((?:\s*' . REG_CRITERES . '\s*)*)(' . REG_FIN_BOUCLE_TROUVE . ')');
     91        . '(' . str_replace('?R', '?3', REG_CRITERES_BOUCLE) . ')(' . REG_FIN_BOUCLE_TROUVE . ')');
    8492
    8593
     
    109117        . '(?:(?:' . REG_NOM_FILTRE_TOUT . '?' . REG_CRITERES_TOUT . '?)*)' // {arguments} |filtre{criteres}
    110118        . ')' . REG_BALISE_COMPLET_STOP ); // ) ... ]
     119
     120
     121
     122
     123if (!function_exists('spip2_geshi_regexp_critere_callback')) {
     124/**
     125 * Cette fonction recupere la liste des criteres de boucle trouves
     126 * "  {critere > 0} {critere=#ENV{tom}}{critere} "
     127 * Elle echappe tous les { et } appartenants au criteres
     128 * en les remplacant par <CRITERE> et </CRITERE>. Ils seront
     129 * remis apres le calcul les arguments de balises / filtres.
     130 *
     131 * Ceci est simplement la pour pouvoir distinguer filtre et critere
     132 * dans la coloration.
     133 *
     134 * @param array $matches
     135 *              Le resultat du preg_match
     136 * @param Object $geshi
     137 *              Instance de l'objet SPIP_GESHI (issu de GESHI)
     138 * @return string
     139 *              La chaine attendu par Geshi
     140 *              qui est quelque chose comme
     141 *              "avant <|!REG3XP31!>contenu|> apres"
     142**/
     143function spip2_geshi_regexp_critere_callback($matches, $geshi) {
     144#var_dump($matches);
     145        $key = $geshi->_hmr_key;
     146        // 0 = tout
     147        // 1 = <BOUCLEx(TABLE)
     148        // 2 = {critere}{critere}
     149        // 3 = />
     150        // L'entree 2 contient les criteres a echapper, et il ne faut pas oublier aussi les espaces possibles.
     151        $criteres = $matches[2];
     152        if (preg_match_all('/(\s*)' . REG_CRITERES_ACCOLADES . '(\s*)/s', $criteres, $crits, PREG_SET_ORDER)) {
     153                $criteres = "";
     154                foreach ($crits as $c) {
     155                        $criteres .=
     156                                  $c[1] // espace
     157                                . "<CRITERE>" // {
     158                                . $c[3] // critere
     159                                . "</CRITERE>" // }
     160                                . $c[5]; // espace
     161                }
     162        }
     163
     164        $retour = $matches[1] . '<|!REG3XP' . $key .'!>'
     165                . str_replace("\n", "|>\n<|!REG3XP" . $key . '!>', $criteres)
     166                . '|>' . $matches[4];
     167        return $retour;
     168}
     169}
     170
    111171
    112172
     
    210270                10 => array(
    211271                        GESHI_SEARCH => REG_BOUCLE_FIN,
    212                         GESHI_REPLACE => '\\4',
     272                        GESHI_REPLACE => '\\3',
    213273                        GESHI_MODIFIERS => '',
    214274                        GESHI_BEFORE => '\\1',
     
    235295
    236296                // criteres de boucle <BOUCLEx(TABLE).../> ( {criteres} )
     297                // on remplace { et } de chaque critere par <CRITERE> pour
     298                // que les filtres 40 ne matchent pas les criteres
     299                // 41 les remets.
    237300                13 => array(
    238301                        GESHI_SEARCH => REG_BOUCLE_CRITERES,
    239                         GESHI_REPLACE => '\\2',
    240                         GESHI_MODIFIERS => '',
    241                         GESHI_BEFORE => '\\1',
    242                         GESHI_AFTER => '\\5'
     302                        SPIP_GESHI_REGEXP_FUNCTION => 'spip2_geshi_regexp_critere_callback',
     303                        GESHI_MODIFIERS => '',
    243304                        ),
    244305
     
    308369                // parametres de filtre, balise
    309370                40 => array(
    310                         GESHI_SEARCH => '(' . REG_CRITERES . '?)',
    311                         GESHI_REPLACE => '\\1',
    312                         GESHI_MODIFIERS => '',
     371                        GESHI_SEARCH => '(' . REG_CRITERES . ')',
     372                        GESHI_REPLACE => '\\1',
     373                        GESHI_MODIFIERS => '',
     374                        GESHI_BEFORE => '',
     375                        GESHI_AFTER => ''
     376                        ),
     377                // remise des accolades de criteres
     378                // echappees pour eviter que filtres 40 ne les matchent
     379                41 => array(
     380                        GESHI_SEARCH => '<CRITERE>(.*)<\/CRITERE>',
     381                        GESHI_REPLACE => '{\\1}',
     382                        GESHI_MODIFIERS => 'Us',
    313383                        GESHI_BEFORE => '',
    314384                        GESHI_AFTER => ''
     
    324394                        GESHI_AFTER => ''
    325395                        ),
     396
    326397                ),
    327        
     398
    328399        'STRICT_MODE_APPLIES' => GESHI_NEVER,
    329400        'SCRIPT_DELIMITERS' => array(),
  • _plugins_/coloration_code/trunk/inc/spip_geshi.php

    r60585 r60666  
    88include_spip('geshi/geshi');
    99
     10// a la sauce GESHI
     11define('SPIP_GESHI_REGEXP_FUNCTION', 99);
     12
     13
     14
    1015class SPIP_GeSHi extends GeSHi {
    1116
    12     /**
    13     * Cette surcharge implemente simplement
    14     * une nouvelle cle dans $language_data
    15     * intitulee 'SPIP_GESHI_COLOR_FUNCTION' permettant d'appeler une fonction
    16     * existante avec le code source a colorier, utilise dans la declaration geshi/spip3.php
    17     *
    18     * Cette fonction doit retourner le code avec les instructions
    19     * en plus de geshi pour colorier, qui sont des choses comme :
    20     * <| class="br0">contenu|>
    21     */
    22     function parse_non_string_part($stuff_to_parse) {
     17        /**
     18        * Cette surcharge implemente simplement
     19        * une nouvelle cle dans $language_data
     20        * intitulee 'SPIP_GESHI_COLOR_FUNCTION' permettant d'appeler une fonction
     21        * existante avec le code source a colorier, utilise dans la declaration geshi/spip3.php
     22        *
     23        * Cette fonction doit retourner le code avec les instructions
     24        * en plus de geshi pour colorier, qui sont des choses comme :
     25        * <| class="br0">contenu|>
     26        */
     27        function parse_non_string_part($stuff_to_parse) {
    2328
    24         // Fonction de coloration definie
    25         // doit s'occuper de retourner des <| et d'echapper les textes (hsc)
    26         if (isset($this->language_data['SPIP_GESHI_COLOR_FUNCTION']) and $this->language_data['SPIP_GESHI_COLOR_FUNCTION']) {
    27             $parse = $this->language_data['SPIP_GESHI_COLOR_FUNCTION'];
    28             $stuff_to_parse = $parse($stuff_to_parse);
    29             # on reprend le minimum syndical de parse_non_string_part()
    30             # en esperant que ca suffise pour ce qu'on a a faire.
    31             # Ca semble que c'est ok.
    32             $stuff_to_parse = str_replace('<|', '<span', $stuff_to_parse);
    33             $stuff_to_parse = str_replace ( '|>', '</span>', $stuff_to_parse );
    34             return $stuff_to_parse;
    35         }
     29                // Fonction de coloration definie
     30                // doit s'occuper de retourner des <| et d'echapper les textes (hsc)
     31                if (isset($this->language_data['SPIP_GESHI_COLOR_FUNCTION']) and $this->language_data['SPIP_GESHI_COLOR_FUNCTION']) {
     32                        $parse = $this->language_data['SPIP_GESHI_COLOR_FUNCTION'];
     33                        $stuff_to_parse = $parse($stuff_to_parse);
     34                        # on reprend le minimum syndical de parse_non_string_part()
     35                        # en esperant que ca suffise pour ce qu'on a a faire.
     36                        # Ca semble que c'est ok.
     37                        $stuff_to_parse = str_replace('<|', '<span', $stuff_to_parse);
     38                        $stuff_to_parse = str_replace ( '|>', '</span>', $stuff_to_parse );
     39                        return $stuff_to_parse;
     40                }
    3641
    37         return parent::parse_non_string_part($stuff_to_parse);
    38     }
     42                return parent::parse_non_string_part($stuff_to_parse);
     43        }
    3944
    40    
     45
     46        /**
     47         * Cette surcharge implemente simplement
     48         * une nouvelle cle dans le tableau de declaration d'une REGEXP
     49         * permettant de passer une fonction via la cle SPIP_GESHI_REGEXP_FUNCTION.
     50         * Cette fonction, si presente, sera appelee avec
     51         * le resultat du match de la regexp, a la place des traitements
     52         * habituels de GESHI, et doit alors retourner le code attendu par GESHI,
     53         * a savoir quelque chose comme : "avant <|!REG3XP31!>contenu|> apres"
     54         *
     55         * Cette possibilite est utilise dans geshi/spip2.php
     56         */
     57        function handle_multiline_regexps($matches) {
     58                $key = $this->_hmr_key;
     59                if (    isset($this->language_data['REGEXPS'][$key][SPIP_GESHI_REGEXP_FUNCTION])
     60                  and $func = $this->language_data['REGEXPS'][$key][SPIP_GESHI_REGEXP_FUNCTION]) {
     61                        return $func($matches, $this);
     62                }
     63
     64                return parent::handle_multiline_regexps($matches);
     65        }
    4166}
    4267
  • _plugins_/coloration_code/trunk/paquet.xml

    r60537 r60666  
    22        prefix="coloration_code"
    33        categorie="edition"
    4         version="0.6.5"
    5         etat="stable"
     4        version="0.7.0-dev"
     5        etat="test"
    66        compatibilite="[2.0.0;3.0.99]"
    77        logo="coloration-32.png"
    88        documentation="http://www.spip-contrib.net/Coloration-Code,2938"
    9 >       
     9>
    1010
    1111        <nom>Coloration Code</nom>
  • _plugins_/coloration_code/trunk/plugin.xml

    r60537 r60666  
    1616        <icon>coloration-32.png</icon>
    1717        <auteur>Pierre Andrews (Mortimer) - ARNO*</auteur>
    18         <version>0.6.5</version>
    19         <etat>stable</etat>
     18        <version>0.7.0-dev</version>
     19        <etat>test</etat>
    2020        <description>
    2121        <multi>
Note: See TracChangeset for help on using the changeset viewer.