source: spip-zone/_plugins_/textwheel/inc/lien.php @ 47717

Last change on this file since 47717 was 47717, checked in by fil@…, 10 years ago

report de r47714 class=auto dans les autoliens

File size: 21.1 KB
Line 
1<?php
2
3/***************************************************************************\
4 *  SPIP, Systeme de publication pour l'internet                           *
5 *                                                                         *
6 *  Copyright (c) 2001-2010                                                *
7 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
8 *                                                                         *
9 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
10 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
11\***************************************************************************/
12
13if (!defined("_ECRIRE_INC_VERSION")) return;
14
15include_spip('base/abstract_sql');
16
17//
18// Production de la balise A+href a partir des raccourcis [xxx->url] etc.
19// Note : complique car c'est ici qu'on applique typo(),
20// et en plus on veut pouvoir les passer en pipeline
21//
22
23function inc_lien_dist($lien, $texte='', $class='', $title='', $hlang='', $rel='', $connect='') {
24        static $u=null;
25        if (!$u) $u=url_de_base();
26        $typo = false;
27
28        // Si une langue est demandee sur un raccourci d'article, chercher
29        // la traduction ;
30        // - [{en}->art2] => traduction anglaise de l'article 2, sinon art 2
31        // - [{}->art2] => traduction en langue courante de l'art 2, sinon art 2
32        if ($hlang
33        AND $match = typer_raccourci($lien)) { 
34                @list($type,,$id,,$args,,$ancre) = $match; 
35                if ($id_trad = sql_getfetsel('id_trad', 'spip_articles', "id_article=$id")
36                AND $id_dest = sql_getfetsel('id_article', 'spip_articles',
37                        "id_trad=$id_trad AND lang=" . sql_quote($hlang))
38                )
39                        $lien = "$type$id_dest";
40                else
41                        $hlang = '';
42        }
43
44        $mode = ($texte AND $class) ? 'url' : 'tout';
45        $lien = calculer_url($lien, $texte, $mode, $connect);
46        if ($mode === 'tout') {
47                $texte = $lien['titre'];
48                if (!$class AND isset($lien['class'])) $class = $lien['class'];
49                $lang = isset($lien['lang']) ?$lien['lang'] : '';
50                $mime = isset($lien['mime']) ? " type='".$lien['mime']."'" : "";
51                $lien = $lien['url'];
52        }
53
54        $lien = trim($lien);
55        if (strncmp($lien,"#",1) == 0)  # ancres pures (internes a la page)
56                $class = 'spip_ancre';
57        elseif (strncasecmp($lien,'mailto:',7)==0) # pseudo URL de mail
58                $class = "spip_mail";
59        elseif (strncmp($texte,'<html>',6)==0) # cf traiter_lien_explicite
60                $class = "spip_url spip_out";
61        elseif (!$class) $class = "spip_out"; # si pas spip_in|spip_glossaire
62
63        // Si l'objet n'est pas de la langue courante, on ajoute hreflang
64        if (!$hlang AND $lang!==$GLOBALS['spip_lang'])
65                $hlang = $lang;
66
67        $lang = ($hlang ? " hreflang='$hlang'" : '');
68
69        if ($title) $title = ' title="'.attribut_html($title).'"';
70
71        // rel=external pour les liens externes
72        if ((strncmp($lien,'http://',7)==0 OR strncmp($lien,'https://',8)==0)
73          AND strncmp("$lien/", $u ,strlen($u))!=0)
74                $rel = trim("$rel external");
75        if ($rel) $rel = " rel='$rel'";
76
77        if (traiter_modeles($texte, false, $echapper ? 'TYPO' : '', $connect)==$texte){
78                $texte = typo($texte, true, $connect);
79                $lien = "<a href=\"".str_replace('"', '&quot;', $lien)."\" class='$class'$lang$title$rel$mime>$texte</a>";
80                return $lien;
81        }
82        # ceci s'execute heureusement avant les tableaux et leur "|".
83        # Attention, le texte initial est deja echappe mais pas forcement
84        # celui retourne par calculer_url.
85        # Penser au cas [<imgXX|right>->URL], qui exige typo('<a>...</a>')
86        $lien = "<a href=\"".str_replace('"', '&quot;', $lien)."\" class='$class'$lang$title$rel$mime>$texte</a>";
87        return typo($lien, true, $connect);
88}
89
90// Regexp des raccourcis, aussi utilisee pour la fusion de sauvegarde Spip
91// Laisser passer des paires de crochets pour la balise multi
92// mais refuser plus d'imbrications ou de mauvaises imbrications
93// sinon les crochets ne peuvent plus servir qu'a ce type de raccourci
94define('_RACCOURCI_LIEN', "/\[([^][]*?([[]\w*[]][^][]*)*)->(>?)([^]]*)\]/msS");
95
96// http://doc.spip.org/@expanser_liens
97function expanser_liens($t, $connect='')
98{
99
100        $t = pipeline('pre_liens', $t);
101
102        expanser_un_lien($connect,'init');
103
104        if (strpos($t, '->') !== false)
105                $t = preg_replace_callback (_RACCOURCI_LIEN, 'expanser_un_lien',$t);
106
107        // on passe a traiter_modeles la liste des liens reperes pour lui permettre
108        // de remettre le texte d'origine dans les parametres du modele
109        $t = traiter_modeles($t, false, false, $connect, expanser_un_lien('','sources'));
110
111        $t = corriger_typo($t);
112
113        $t = expanser_un_lien($t,'reinsert');
114
115        return $t;
116}
117
118
119function expanser_un_lien($reg, $quoi='echappe'){
120        static $pile = array();
121        static $inserts;
122        static $sources;
123        static $regs;
124        static $k = 0;
125        static $lien;
126        static $connect='';
127
128        switch ($quoi){
129                case 'init':
130                        if (!$lien) $lien = charger_fonction('lien', 'inc');
131                        array_push($pile,array($inserts,$sources,$regs,$connect,$k));
132                        $inserts = $sources = $regs = array();
133                        $connect = $reg; // stocker le $connect pour les appels a inc_lien_dist
134                        $k=0;
135                        return;
136                        break;
137                case 'echappe':
138                        $inserts[$k] = '@@SPIP_ECHAPPE_LIEN_' . $k . '@@';
139                        $sources[$k] = $reg[0];
140
141                        #$titre=$reg[1];
142                        list($titre, $bulle, $hlang) = traiter_raccourci_lien_atts($reg[1]);
143                        $r = end($reg);
144                        // la mise en lien automatique est passee par la a tort !
145                        // corrigeons pour eviter d'avoir un <a...> dans un href...
146                        if (strncmp($r,'<a',2)==0){
147                                $href = extraire_attribut($r, 'href');
148                                // remplacons dans la source qui peut etre reinjectee dans les arguments
149                                // d'un modele
150                                $sources[$k] = str_replace($r,$href,$sources[$k]);
151                                // et prenons le href comme la vraie url a linker
152                                $r = $href;
153                        }
154                        $regs[$k] = $lien($r, $titre, '', $bulle, $hlang, '', $connect);
155                        return $inserts[$k++];
156                        break;
157                case 'reinsert':
158                        if (count($inserts))
159                                $reg = str_replace($inserts, $regs, $reg);
160                        list($inserts,$sources,$regs,$connect,$k) = array_pop($pile);
161                        return $reg;
162                        break;
163                case 'sources':
164                        return array($inserts, $sources);
165                        break;
166        }
167}
168
169// Meme analyse mais pour eliminer les liens
170// et ne laisser que leur titre, a expliciter si ce n'est fait
171// http://doc.spip.org/@nettoyer_raccourcis_typo
172function nettoyer_raccourcis_typo($texte, $connect='')
173{
174        $texte = pipeline('nettoyer_raccourcis_typo',$texte);
175
176        if (preg_match_all(_RACCOURCI_LIEN, $texte, $regs, PREG_SET_ORDER))
177                foreach ($regs as $reg) {
178                        list ($titre,,)= traiter_raccourci_lien_atts($reg[1]);
179                        if (!$titre) {
180                                $match = typer_raccourci($reg[count($reg)-1]);
181                                @list($type,,$id,,,,) = $match;
182                                if ($type) {
183                                        $url = generer_url_entite($id,$type,'','',true);
184                                        if (is_array($url)) list($type, $id) = $url;
185                                        $titre = traiter_raccourci_titre($id, $type, $connect);
186                                }
187                                $titre = $titre ? $titre['titre'] : $match[0];
188                        }
189                        $titre = corriger_typo(supprimer_tags($titre));
190                        $texte = str_replace($reg[0], $titre, $texte);
191                }
192
193        // supprimer les notes
194        $texte = preg_replace(",[[][[]([^]]|[]][^]])*[]][]],UimsS","",$texte);
195
196        // supprimer les codes typos
197        $texte = str_replace(array('}','{'), '', $texte);
198
199        // supprimer les tableaux
200        $texte = preg_replace(",(^|\r)\|.*\|\r,s", "\r", $texte);
201
202        return $texte;
203}
204
205
206
207// Repere dans la partie texte d'un raccourci [texte->...]
208// la langue et la bulle eventuelles
209
210define('_RACCOURCI_ATTRIBUTS', '/^(.*?)([|]([^<>]*?))?([{]([a-z_]*)[}])?$/');
211
212// http://doc.spip.org/@traiter_raccourci_lien_atts
213function traiter_raccourci_lien_atts($texte) {
214
215        $bulle = $hlang = '';
216        // title et hreflang donnes par le raccourci ?
217        if (strpbrk($texte, "|{") !== false AND
218          preg_match(_RACCOURCI_ATTRIBUTS, $texte, $m)) {
219
220                $n =count($m);
221                // |infobulle ?
222                if ($n > 2) {
223                        $bulle = $m[3];
224                        // {hreflang} ?
225                        if ($n > 4) {
226                        // si c'est un code de langue connu, on met un hreflang
227                                if (traduire_nom_langue($m[5]) <> $m[5]) {
228                                        $hlang = $m[5];
229                                } elseif (!$m[5]) {
230                                        $hlang = test_espace_prive() ?
231                                          $GLOBALS['lang_objet'] : $GLOBALS['spip_lang'];
232                                // sinon c'est un italique
233                                } else {
234                                        $m[1] .= $m[4];
235                                }
236
237                        // S'il n'y a pas de hreflang sous la forme {}, ce qui suit le |
238                        // est peut-etre une langue
239                        } else if (preg_match('/^[a-z_]+$/', $m[3])) {
240                        // si c'est un code de langue connu, on met un hreflang
241                        // mais on laisse le title (c'est arbitraire tout ca...)
242                                if (traduire_nom_langue($m[3]) <> $m[3]) {
243                                  $hlang = $m[3];
244                                }
245                        }
246                }
247                $texte = $m[1];
248        }
249
250        return array(trim($texte), $bulle, $hlang);
251}
252
253define('_EXTRAIRE_DOMAINE', '/^(?:[^\W_]((?:[^\W_]|-){0,61}[^\W_,])?\.)+[a-z]{2,6}\b/Si');
254
255// callback pour la fonction traiter_raccourci_liens()
256// http://doc.spip.org/@autoliens_callback
257function traiter_autoliens($r) {
258        if (count($r)<2) return reset($r);
259        list($tout, $l) = $r;
260        if (!$l) return $tout;
261        // reperer le protocole
262        if (preg_match(',^(https?):/*,S', $l, $m)) {
263                $l = substr($l, strlen($m[0]));
264                $protocol = $m[1];
265        } else  $protocol = 'http';
266        // valider le nom de domaine
267        if (!preg_match(_EXTRAIRE_DOMAINE, $l)) return $tout;
268        // supprimer les ponctuations a la fin d'une URL
269        preg_match('/^(.*?)([,.;?]?)$/', $l, $k);
270        $url = $protocol.'://'.$k[1];
271        $lien = charger_fonction('lien', 'inc');
272        $r = $lien($url,'','','','','nofollow') . $k[2];
273
274        // ajouter la class auto
275        $r = inserer_attribut($r, 'class', trim(extraire_attribut($r,'class').' auto'));
276
277        // si l'original ne contenait pas le 'http:' on le supprime du clic
278        return $m ? $r : str_replace('>http://', '>', $r);
279}
280
281define('_EXTRAIRE_LIENS', ',' . '\[[^\[\]]*(?:<-|->).*?\]' . '|<a\b.*?</a\b' . '|<\w.*?>' . '|((?:https?:/|www\.)[^"\'\s\[\]\}\)<>]*)' .',imsS');
282
283// Les URLs brutes sont converties en <a href='url'>url</a>
284// http://doc.spip.org/@traiter_raccourci_liens
285function traiter_raccourci_liens($t) {
286        return preg_replace_callback(_EXTRAIRE_LIENS, 'traiter_autoliens', $t);
287}
288
289// Fonction pour les champs chapo commencant par =,  redirection qui peut etre:
290// 1. un raccourci Spip habituel (premier If) [texte->TYPEnnn]
291// 2. un ultra raccourci TYPEnnn voire nnn (article) (deuxieme If)
292// 3. une URL std
293// renvoie une tableau structure comme ci-dessus mais sans calcul d'URL
294// (cf fusion de sauvegardes)
295
296define('_RACCOURCI_CHAPO', '/^(\W*)(\W*)(\w*\d+([?#].*)?)$/');
297
298// http://doc.spip.org/@chapo_redirige
299function chapo_redirige($chapo, $url=false)
300{
301        if (!preg_match(_RACCOURCI_LIEN, $chapo, $m))
302                if (!preg_match(_RACCOURCI_CHAPO, $chapo, $m))
303                        return $chapo;
304
305        return !$url ? $m[3] : traiter_lien_implicite($m[3]);
306}
307
308// Ne pas afficher le chapo si article virtuel
309// http://doc.spip.org/@nettoyer_chapo
310function nettoyer_chapo($chapo){
311        return (substr($chapo,0,1) == "=") ? '' : $chapo;
312}
313
314// http://doc.spip.org/@chapo_redirigetil
315function chapo_redirigetil($chapo) { return $chapo && $chapo[0] == '=';}
316
317// Cherche un lien du type [->raccourci 123]
318// associe a une fonction generer_url_raccourci() definie explicitement
319// ou implicitement par le jeu de type_urls courant.
320//
321// Valeur retournee selon le parametre $pour:
322// 'tout' : tableau d'index url,class,titre,lang (vise <a href="U" class='C' hreflang='L'>T</a>)
323// 'titre': seulement T ci-dessus (i.e. le TITRE ci-dessus ou dans table SQL)
324// 'url':   seulement U  (i.e. generer_url_RACCOURCI)
325
326// http://doc.spip.org/@calculer_url
327function calculer_url ($ref, $texte='', $pour='url', $connect='') {
328        $r = traiter_lien_implicite($ref, $texte, $pour, $connect);
329        return $r ? $r : traiter_lien_explicite($ref, $texte, $pour, $connect);
330}
331
332define('_EXTRAIRE_LIEN', ",^\s*(http:?/?/?|mailto:?)\s*$,iS");
333
334// http://doc.spip.org/@traiter_lien_explicite
335function traiter_lien_explicite ($ref, $texte='', $pour='url', $connect='')
336{
337        if (preg_match(_EXTRAIRE_LIEN, $ref))
338                return ($pour != 'tout') ? '' : array('','','','');
339
340        $lien = entites_html(trim($ref));
341
342        // Liens explicites
343        if (!$texte) {
344                $texte = str_replace('"', '', $lien);
345                // evite l'affichage de trops longues urls.
346                // personnalisation possible dans mes_options
347                $long_url = defined('_MAX_LONG_URL') ? _MAX_LONG_URL : 40;
348                $coupe_url = defined('_MAX_COUPE_URL') ? _MAX_COUPE_URL : 35;
349                if (strlen($texte)>$long_url) {
350                        $texte = substr($texte,0,$coupe_url).'...';
351                }
352                $texte = "<html>".quote_amp($texte)."</html>";
353        }
354
355        // petites corrections d'URL
356        if (preg_match('/^www\.[^@]+$/S',$lien))
357                $lien = "http://".$lien;
358        else if (strpos($lien, "@") && email_valide($lien)) {
359                if (!$texte) $texte = $lien;
360                $lien = "mailto:".$lien;
361        }
362       
363        if ($pour == 'url') return $lien;
364
365        if ($pour == 'titre') return $texte;
366
367        return array('url' => $lien, 'titre' => $texte);
368}
369
370function liens_implicite_glose_dist($texte,$id,$type,$args,$ancre,$connect=''){
371        if (function_exists($f = 'glossaire_' . $ancre))
372                $url = $f($texte, $id);
373        else
374                $url = glossaire_std($texte);
375        return $url;
376}
377
378
379/* fonction valable pour SPIP 2.1 seulement [ en 2.3 elle est definie dans l'extension "Sites" ] // */
380function liens_implicite_site_dist($texte,$id,$type,$args,$ancre,$connect=''){
381        if (!$id = intval($id))
382                return false;
383        $url = sql_getfetsel('url_site', 'spip_syndic', "id_syndic=".intval($id),'','','','',$connect);
384        return $url;
385}
386/* fin exception spip 2.1 */
387
388
389// http://doc.spip.org/@traiter_lien_implicite
390function traiter_lien_implicite ($ref, $texte='', $pour='url', $connect='')
391{
392        if (!($match = typer_raccourci($ref))) return false;
393        @list($type,,$id,,$args,,$ancre) = $match;
394# attention dans le cas des sites le lien doit pointer non pas sur
395# la page locale du site, mais directement sur le site lui-meme
396        if ($f = charger_fonction("implicite_$type","liens",true))
397                $url = $f($texte,$id,$type,$args,$ancre,$connect);
398        if (!$url)
399                $url = generer_url_entite($id,$type,$args,$ancre,$connect ? $connect : NULL);
400        if (!$url) return false;
401        if (is_array($url)) {
402                @list($type,$id) = $url;
403                $url = generer_url_entite($id,$type,$args,$ancre,$connect ? $connect : NULL);
404        }
405        if ($pour === 'url') return $url;
406        $r = traiter_raccourci_titre($id, $type, $connect);
407        if ($r) $r['class'] =  ($type == 'site')?'spip_out':'spip_in';
408        if ($texte = trim($texte)) $r['titre'] = $texte;
409        if (!@$r['titre']) $r['titre'] =  _T($type) . " $id";
410        if ($pour=='titre') return $r['titre'];
411        $r['url'] = $url;
412
413        // dans le cas d'un lien vers un doc, ajouter le type='mime/type'
414        if ($type == 'document'
415        AND $mime = sql_getfetsel('mime_type', 'spip_types_documents',
416                        "extension IN (SELECT extension FROM spip_documents where id_document =".sql_quote($id).")",
417                        '','','','',$connect)
418        )
419                $r['mime'] = $mime;
420
421        return $r;
422}
423
424// analyse des raccourcis issus de [TITRE->RACCOURCInnn] et connexes
425
426define('_RACCOURCI_URL', '/^\s*(\w*?)\s*(\d+)(\?(.*?))?(#([^\s]*))?\s*$/S');
427
428// http://doc.spip.org/@typer_raccourci
429function typer_raccourci ($lien) {
430        if (!preg_match(_RACCOURCI_URL, $lien, $match)) return array();
431        $f = $match[1];
432        // valeur par defaut et alias historiques
433        if (!$f) $f = 'article';
434        else if ($f == 'art') $f = 'article';
435        else if ($f == 'br') $f = 'breve';
436        else if ($f == 'rub') $f = 'rubrique';
437        else if ($f == 'aut') $f = 'auteur';
438        else if ($f == 'doc' OR $f == 'im' OR $f == 'img' OR $f == 'image' OR $f == 'emb')
439                $f = 'document';
440        else if (preg_match('/^br..?ve$/S', $f)) $f = 'breve'; # accents :(
441        $match[0] = $f;
442        return $match;
443}
444
445// Retourne le champ textuel associe a une cle primaire, et sa langue
446function traiter_raccourci_titre($id, $type, $connect=NULL)
447{
448        $trouver_table = charger_fonction('trouver_table', 'base');
449        $desc = $trouver_table(table_objet($type));
450        if (!($desc AND $s = $desc['titre'])) return array();
451        $_id = $desc['key']['PRIMARY KEY'];
452        $r = sql_fetsel($s, $desc['table'], "$_id=$id", '','','','',$connect);
453        if (!$r) return array();
454        $r['titre'] = supprimer_numero($r['titre']);
455        if (!$r['titre']) $r['titre'] = $r['surnom'];
456        if (!isset($r['lang'])) $r['lang'] = '';
457        return $r;
458}
459
460// traite les modeles (dans la fonction typo), en remplacant
461// le raccourci <modeleN|parametres> par la page calculee a
462// partir du squelette modeles/modele.html
463// Le nom du modele doit faire au moins trois caracteres (evite <h2>)
464// Si $doublons==true, on repere les documents sans calculer les modeles
465// mais on renvoie les params (pour l'indexation par le moteur de recherche)
466// http://doc.spip.org/@traiter_modeles
467
468define('_RACCOURCI_MODELE', 
469         '(<([a-z_-]{3,})' # <modele
470        .'\s*([0-9]*)\s*' # id
471        .'([|](?:<[^<>]*>|[^>])*?)?' # |arguments (y compris des tags <...>)
472        .'\s*/?'.'>)' # fin du modele >
473        .'\s*(<\/a>)?' # eventuel </a>
474       );
475
476define('_RACCOURCI_MODELE_DEBUT', '@^' . _RACCOURCI_MODELE .'@isS');
477
478// http://doc.spip.org/@traiter_modeles
479function traiter_modeles($texte, $doublons=false, $echap='', $connect='', $liens = null) {
480        // preserver la compatibilite : true = recherche des documents
481        if ($doublons===true)
482                $doublons = array('documents'=>array('doc','emb','img'));
483        // detecter les modeles (rapide)
484        if (strpos($texte,"<")!==false AND
485          preg_match_all('/<[a-z_-]{3,}\s*[0-9|]+/iS', $texte, $matches, PREG_SET_ORDER)) {
486                include_spip('public/assembler');
487                foreach ($matches as $match) {
488                        // Recuperer l'appel complet (y compris un eventuel lien)
489
490                        $a = strpos($texte,$match[0]);
491                        preg_match(_RACCOURCI_MODELE_DEBUT,
492                        substr($texte, $a), $regs);
493                        $regs[]=""; // s'assurer qu'il y a toujours un 5e arg, eventuellement vide
494                        list(,$mod, $type, $id, $params, $fin) = $regs;
495                        if ($fin AND
496                        preg_match('/<a\s[^<>]*>\s*$/i',
497                                        substr($texte, 0, $a), $r)) {
498                                $lien = array(
499                                        'href' => extraire_attribut($r[0],'href'),
500                                        'class' => extraire_attribut($r[0],'class'),
501                                        'mime' => extraire_attribut($r[0],'type')
502                                );
503                                $n = strlen($r[0]);
504                                $a -= $n;
505                                $cherche = $n + strlen($regs[0]);
506                        } else {
507                                $lien = false;
508                                $cherche = strlen($mod);
509                        }
510
511                        // calculer le modele
512                        # hack articles_edit, breves_edit, indexation
513                        if ($doublons)
514                                $texte .= preg_replace(',[|][^|=]*,s',' ',$params);
515                        # version normale
516                        else {
517                                // si un tableau de liens a ete passe, reinjecter le contenu d'origine
518                                // dans les parametres, plutot que les liens echappes
519                                if (!is_null($liens))
520                                        $params = str_replace($liens[0], $liens[1], $params);
521                          $modele = inclure_modele($type, $id, $params, $lien, $connect);
522                                // en cas d'echec,
523                                // si l'objet demande a une url,
524                                // creer un petit encadre vers elle
525                                if ($modele === false) {
526                                        if (!$lien)
527                                                $lien = traiter_lien_implicite("$type$id", '', 'tout', $connect);
528                                        if ($lien)
529                                                $modele = '<a href="'
530                                                  .$lien['url']
531                                                  .'" class="spip_modele'
532                                                  . '">'
533                                                  .sinon($lien['titre'], _T('ecrire:info_sans_titre'))
534                                                  ."</a>";
535                                        else {
536                                                $modele = "";
537                                                if (test_espace_prive()) {
538                                                        $modele = entites_html(substr($texte,$a,$cherche));
539                                                        if (!is_null($liens))
540                                                                $modele = "<pre>".str_replace($liens[0], $liens[1], $modele)."</pre>";
541                                                }
542                                        }
543                                }
544                                // le remplacer dans le texte
545                                if ($modele !== false) {
546                                        $modele = protege_js_modeles($modele);
547                                        $rempl = code_echappement($modele, $echap);
548                                        $texte = substr($texte, 0, $a)
549                                                . $rempl
550                                                . substr($texte, $a+$cherche);
551                                }
552                        }
553
554                        // hack pour tout l'espace prive
555                        if (((!_DIR_RESTREINT) OR ($doublons)) AND ($id)){
556                                foreach($doublons?$doublons:array('documents'=>array('doc','emb','img')) as $quoi=>$modeles)
557                                        if (in_array($type,$modeles))
558                                                $GLOBALS["doublons_{$quoi}_inclus"][] = $id;
559                        }
560                }
561        }
562
563        return $texte;
564}
565
566//
567// Raccourcis ancre [#ancre<-]
568//
569
570define('_RACCOURCI_ANCRE', "/\[#?([^][]*)<-\]/S");
571
572// http://doc.spip.org/@traiter_raccourci_ancre
573function traiter_raccourci_ancre($letexte)
574{
575        if (preg_match_all(_RACCOURCI_ANCRE, $letexte, $m, PREG_SET_ORDER))
576        foreach ($m as $regs)
577                $letexte = str_replace($regs[0],
578                '<a name="'.entites_html($regs[1]).'"></a>', $letexte);
579        return $letexte;
580}
581
582//
583// Raccourcis automatiques [?SPIP] vers un glossaire
584// Wikipedia par defaut, avec ses contraintes techniques
585// cf. http://fr.wikipedia.org/wiki/Wikip%C3%A9dia:Conventions_sur_les_titres
586
587define('_RACCOURCI_GLOSSAIRE', "/\[\?+\s*([^][<>]+)\]/S");
588define('_RACCOURCI_GLOSES', '/^([^|#{]*\w[^|#{]*)([^#]*)(#([^|{}]*))?(.*)$/S');
589
590// http://doc.spip.org/@traiter_raccourci_glossaire
591function traiter_raccourci_glossaire($texte)
592{
593        if (!preg_match_all(_RACCOURCI_GLOSSAIRE,
594        $texte, $matches, PREG_SET_ORDER))
595                return $texte;
596
597        include_spip('inc/charsets');
598        $lien = charger_fonction('lien', 'inc');
599
600        foreach ($matches as $regs) {
601        // Eviter les cas particulier genre "[?!?]"
602        // et isoler le lexeme a gloser de ses accessoires
603        // (#:url du glossaire, | bulle d'aide, {} hreflang)
604        // Transformation en pseudo-raccourci pour passer dans inc_lien
605                if (preg_match(_RACCOURCI_GLOSES, $regs[1], $r)) {
606                        preg_match('/^(.*?)(\d*)$/', $r[4], $m);
607                        $_n = intval($m[2]);
608                        $gloss = $m[1] ? ('#' . $m[1]) : '';
609                        $t = $r[1] . $r[2] . $r[5];
610                        list($t, $bulle, $hlang) = traiter_raccourci_lien_atts($t);
611                        $t = unicode2charset(charset2unicode($t), 'utf-8');
612                        $ref = $lien("glose$_n$gloss", $t, 'spip_glossaire', $bulle, $hlang);
613                        $texte = str_replace($regs[0], $ref, $texte);
614                }
615        }
616        return $texte;
617}
618
619// http://doc.spip.org/@glossaire_std
620function glossaire_std($terme)
621{
622        global $url_glossaire_externe;
623        static $pcre = NULL;
624
625        if ($pcre === NULL) {
626                $pcre = isset($GLOBALS['meta']['pcre_u']) 
627                ? $GLOBALS['meta']['pcre_u']
628                  : '';
629                if (strpos($url_glossaire_externe, "%s") === false)
630                        $url_glossaire_externe .= '%s';
631        }
632
633        $glosateur = str_replace("@lang@",
634                                $GLOBALS['spip_lang'],
635                                $GLOBALS['url_glossaire_externe']);
636
637        $terme = rawurlencode(preg_replace(',\s+,'.$pcre, '_', $terme));
638       
639        return  str_replace("%s", $terme, $glosateur);
640}
641
642?>
Note: See TracBrowser for help on using the repository browser.