[SPIP] v3.2.1-->v3.2.2
[lhc/web/www.git] / www / ecrire / inc / math.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2019 *
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
13
14 //
15 if (!defined('_ECRIRE_INC_VERSION')) {
16 return;
17 }
18
19 //
20 // Gestion du raccourci <math>...</math> en client-serveur
21 //
22
23 // http://code.spip.net/@image_math
24 function produire_image_math($tex) {
25
26 switch ($GLOBALS['traiter_math']) {
27 // Attention: mathml desactiv'e pour l'instant
28 case 'mathml':
29 $ext = '.xhtml';
30 $server = $GLOBALS['mathml_server'];
31 break;
32 case 'tex':
33 $ext = '.png';
34 $server = $GLOBALS['tex_server'];
35 break;
36 default:
37 return $tex;
38 }
39
40 // Regarder dans le repertoire local des images TeX et blocs MathML
41 if (!@is_dir($dir_tex = _DIR_VAR . 'cache-TeX/')) {
42 @mkdir($dir_tex, _SPIP_CHMOD);
43 }
44 $fichier = $dir_tex . md5(trim($tex)) . $ext;
45
46
47 if (!@file_exists($fichier)) {
48 // Aller chercher l'image sur le serveur
49 if ($server) {
50 spip_log($url = $server . '?' . rawurlencode($tex));
51 include_spip('inc/distant');
52 recuperer_page($url, $fichier);
53 }
54 }
55
56
57 // Composer la reponse selon presence ou non de l'image
58 $tex = entites_html($tex);
59 if (@file_exists($fichier)) {
60
61 // MathML
62 if ($GLOBALS['traiter_math'] == 'mathml') {
63 return join(file("$fichier"), "");
64 } // TeX
65 else {
66 list(, , , $size) = @getimagesize($fichier);
67 $alt = "alt=\"$tex\" title=\"$tex\"";
68
69 return "<img src=\"$fichier\" style=\"vertical-align:middle;\" $size $alt />";
70 }
71
72 } else // pas de fichier
73 {
74 return "<tt><span class='spip_code' dir='ltr'>$tex</span></tt>";
75 }
76
77 }
78
79
80 /**
81 * Active la recherche et l'affichage d'expressions mathématiques dans le texte
82 * transmis, dans tous les textes à l'intérieur d'une balise `<math>`.
83 *
84 * Encadrer un texte de balises `<math> ... </math>` active la recherche
85 * d'expressions mathématiques écrites entre caractères `$` au sein de ce texte :
86 *
87 * - `$$expression$$` traitera l'expression comme un paragraphe centré (p)
88 * - `$expression$` traitera l'expression comme un texte en ligne (span)
89 *
90 * Un serveur distant calculera une image à partir de l'expression mathématique
91 * donnée. Cette image est mise en cache localement (local/cache-Tex)
92 *
93 * @note
94 * Si cette fonction est appelée depuis `propre()` alors un échappement
95 * des caractères `&` en `&amp;` a été réalisé, qu'il faut redéfaire
96 * dans les expressions mathématiques trouvées (utiliser l'option
97 * `$defaire_amp` à true pour cela).
98 *
99 * @link http://www.spip.net/3016
100 * @uses produire_image_math()
101 * @uses code_echappement()
102 *
103 * @param string $letexte
104 * @param string $source
105 * @param bool $defaire_amp
106 * true pour passer les `&amp;` en `&` dans les expressions mathématiques.
107 * @return string
108 */
109 function traiter_math($letexte, $source = '', $defaire_amp = false) {
110
111 $texte_a_voir = $letexte;
112 while (($debut = strpos($texte_a_voir, "<math>")) !== false) {
113 if (!$fin = strpos($texte_a_voir, "</math>")) {
114 $fin = strlen($texte_a_voir);
115 }
116
117 $texte_debut = substr($texte_a_voir, 0, $debut);
118 $texte_milieu = substr($texte_a_voir,
119 $debut + strlen("<math>"), $fin - $debut - strlen("<math>"));
120 $texte_fin = substr($texte_a_voir,
121 $fin + strlen("</math>"), strlen($texte_a_voir));
122
123 // Les doubles $$x^2$$ en mode 'div'
124 while ((preg_match(",[$][$]([^$]+)[$][$],", $texte_milieu, $regs))) {
125 $expression = $regs[1];
126 if ($defaire_amp) {
127 $expression = str_replace('&amp;', '&', $expression);
128 }
129 $echap = "\n<p class=\"spip\" style=\"text-align: center;\">" . produire_image_math($expression) . "</p>\n";
130 $pos = strpos($texte_milieu, $regs[0]);
131 $texte_milieu = substr($texte_milieu, 0, $pos)
132 . code_echappement($echap, $source)
133 . substr($texte_milieu, $pos + strlen($regs[0]));
134 }
135
136 // Les simples $x^2$ en mode 'span'
137 while ((preg_match(",[$]([^$]+)[$],", $texte_milieu, $regs))) {
138 $expression = $regs[1];
139 if ($defaire_amp) {
140 $expression = str_replace('&amp;', '&', $expression);
141 }
142 $echap = produire_image_math($expression);
143 $pos = strpos($texte_milieu, $regs[0]);
144 $texte_milieu = substr($texte_milieu, 0, $pos)
145 . code_echappement($echap, $source)
146 . substr($texte_milieu, $pos + strlen($regs[0]));
147 }
148
149 $texte_a_voir = $texte_debut . $texte_milieu . $texte_fin;
150 }
151
152 return $texte_a_voir;
153 }