88f22bfef260d378af8b651f4812ef87e7fe6382
[moodle.git] / filter / mathjaxloader / filter.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * This filter provides automatic support for MathJax
19  *
20  * @package    filter_mathjaxloader
21  * @copyright  2013 Damyon Wiese (damyon@moodle.com)
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 defined('MOODLE_INTERNAL') || die();
27 /**
28  * Mathjax filtering
29  */
30 class filter_mathjaxloader extends moodle_text_filter {
32     /*
33      * Perform a mapping of the moodle language code to the equivalent for MathJax.
34      *
35      * @param string $moodlelangcode - The moodle language code - e.g. en_pirate
36      * @return string The MathJax language code.
37      */
38     public function map_language_code($moodlelangcode) {
39         $mathjaxlangcodes = array('br',
40                                   'cdo',
41                                   'cs',
42                                   'da',
43                                   'de',
44                                   'en',
45                                   'eo',
46                                   'es',
47                                   'fa',
48                                   'fi',
49                                   'fr',
50                                   'gl',
51                                   'he',
52                                   'ia',
53                                   'it',
54                                   'ja',
55                                   'ko',
56                                   'lb',
57                                   'mk',
58                                   'nl',
59                                   'oc',
60                                   'pl',
61                                   'pt',
62                                   'pt-br',
63                                   'ru',
64                                   'sl',
65                                   'sv',
66                                   'tr',
67                                   'uk',
68                                   'zh-hans');
69         $exceptions = array('cz' => 'cs');
71         // First see if this is an exception.
72         if (isset($exceptions[$moodlelangcode])) {
73             $moodlelangcode = $exceptions[$moodlelangcode];
74         }
76         // Now look for an exact lang string match.
77         if (in_array($moodlelangcode, $mathjaxlangcodes)) {
78             return $moodlelangcode;
79         }
81         // Now try shortening the moodle lang string.
82         $moodlelangcode = preg_replace('/-.*/', '', $moodlelangcode);
83         // Look for a match on the shortened string.
84         if (in_array($moodlelangcode, $mathjaxlangcodes)) {
85             return $moodlelangcode;
86         }
87         // All failed - use english.
88         return 'en';
89     }
91     /*
92      * Add the javascript to enable mathjax processing on this page.
93      *
94      * @param moodle_page $page The current page.
95      * @param context $context The current context.
96      */
97     public function setup($page, $context) {
98         // This only requires execution once per request.
99         static $jsinitialised = false;
101         if (empty($jsinitialised)) {
102             if (is_https()) {
103                 $url = get_config('filter_mathjaxloader', 'httpsurl');
104             } else {
105                 $url = get_config('filter_mathjaxloader', 'httpurl');
106             }
107             $lang = $this->map_language_code(current_language());
108             $url = new moodle_url($url, array('delayStartupUntil' => 'configured'));
110             $moduleconfig = array(
111                 'name' => 'mathjax',
112                 'fullpath' => $url
113             );
115             $page->requires->js_module($moduleconfig);
117             $config = get_config('filter_mathjaxloader', 'mathjaxconfig');
119             $params = array('mathjaxconfig' => $config, 'lang' => $lang);
121             $page->requires->yui_module('moodle-filter_mathjaxloader-loader', 'M.filter_mathjaxloader.configure', array($params));
123             $jsinitialised = true;
124         }
125     }
127     /*
128      * This function wraps the filtered text in a span, that mathjaxloader is configured to process.
129      *
130      * @param string $text The text to filter.
131      * @param array $options The filter options.
132      */
133     public function filter($text, array $options = array()) {
134         global $PAGE;
136         $legacy = get_config('filter_mathjaxloader', 'texfiltercompatibility');
137         $extradelimiters = explode(',', get_config('filter_mathjaxloader', 'additionaldelimiters'));
138         if ($legacy) {
139             // This replaces any of the tex filter maths delimiters with the default for inline maths in MathJAX "\( blah \)".
140             // E.g. "<tex.*> blah </tex>".
141             $text = preg_replace('|<(/?) *tex( [^>]*)?>|u', '[\1tex]', $text);
142             // E.g. "[tex.*] blah [/tex]".
143             $text = str_replace('[tex]', '\\(', $text);
144             $text = str_replace('[/tex]', '\\)', $text);
145             // E.g. "$$ blah $$".
146             $text = preg_replace('|\$\$([\S\s]*?)\$\$|u', '\\(\1\\)', $text);
147             // E.g. "\[ blah \]".
148             $text = str_replace('\\[', '\\(', $text);
149             $text = str_replace('\\]', '\\)', $text);
150         }
152         $hasinline = strpos($text, '\\(') !== false && strpos($text, '\\)') !== false;
153         $hasdisplay = (strpos($text, '$$') !== false) ||
154                       (strpos($text, '\\[') !== false && strpos($text, '\\]') !== false);
156         $hasextra = false;
158         foreach ($extradelimiters as $extra) {
159             if ($extra && strpos($text, $extra) !== false) {
160                 $hasextra = true;
161                 break;
162             }
163         }
164         if ($hasinline || $hasdisplay || $hasextra) {
165             $PAGE->requires->yui_module('moodle-filter_mathjaxloader-loader', 'M.filter_mathjaxloader.typeset');
166             if ($hasextra) {
167                 $text = '<span class="nolink">' + $text + '</span>';
168             } else {
169                 if ($hasinline) {
170                     $text = preg_replace('/\\\\\\([\S\s]*?\\\\\\)/u',
171                         '<span class="nolink">\0</span>', $text);
172                 }
173                 if ($hasdisplay) {
174                     $text = preg_replace('/\$\$[\S\s]*?\$\$|\\\\\\[[\S\s]*?\\\\\\]/u',
175                         '<span class="nolink">\0</span>', $text);
176                 }
177             }
178             return '<span class="filter_mathjaxloader_equation">' . $text . '</span>';
179         }
180         return $text;
181     }