PageRenderTime 56ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/spip/ecrire/inc/lien.php

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