MDL-53572 mathjax: always load mathjax using https
[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             $url = get_config('filter_mathjaxloader', 'httpsurl');
103             $lang = $this->map_language_code(current_language());
104             $url = new moodle_url($url, array('delayStartupUntil' => 'configured'));
106             $moduleconfig = array(
107                 'name' => 'mathjax',
108                 'fullpath' => $url
109             );
111             $page->requires->js_module($moduleconfig);
113             $config = get_config('filter_mathjaxloader', 'mathjaxconfig');
115             $params = array('mathjaxconfig' => $config, 'lang' => $lang);
117             $page->requires->yui_module('moodle-filter_mathjaxloader-loader', 'M.filter_mathjaxloader.configure', array($params));
119             $jsinitialised = true;
120         }
121     }
123     /*
124      * This function wraps the filtered text in a span, that mathjaxloader is configured to process.
125      *
126      * @param string $text The text to filter.
127      * @param array $options The filter options.
128      */
129     public function filter($text, array $options = array()) {
130         global $PAGE;
132         $legacy = get_config('filter_mathjaxloader', 'texfiltercompatibility');
133         $extradelimiters = explode(',', get_config('filter_mathjaxloader', 'additionaldelimiters'));
134         if ($legacy) {
135             // This replaces any of the tex filter maths delimiters with the default for inline maths in MathJAX "\( blah \)".
136             // E.g. "<tex.*> blah </tex>".
137             $text = preg_replace('|<(/?) *tex( [^>]*)?>|u', '[\1tex]', $text);
138             // E.g. "[tex.*] blah [/tex]".
139             $text = str_replace('[tex]', '\\(', $text);
140             $text = str_replace('[/tex]', '\\)', $text);
141             // E.g. "$$ blah $$".
142             $text = preg_replace('|\$\$([\S\s]*?)\$\$|u', '\\(\1\\)', $text);
143             // E.g. "\[ blah \]".
144             $text = str_replace('\\[', '\\(', $text);
145             $text = str_replace('\\]', '\\)', $text);
146         }
148         $hasinline = strpos($text, '\\(') !== false && strpos($text, '\\)') !== false;
149         $hasdisplay = (strpos($text, '$$') !== false) ||
150                       (strpos($text, '\\[') !== false && strpos($text, '\\]') !== false);
152         $hasextra = false;
154         foreach ($extradelimiters as $extra) {
155             if ($extra && strpos($text, $extra) !== false) {
156                 $hasextra = true;
157                 break;
158             }
159         }
160         if ($hasinline || $hasdisplay || $hasextra) {
161             $PAGE->requires->yui_module('moodle-filter_mathjaxloader-loader', 'M.filter_mathjaxloader.typeset');
162             if ($hasextra) {
163                 // If custom dilimeters are used, wrap whole text to prevent autolinking.
164                 $text = '<span class="nolink">' + $text + '</span>';
165             } else {
166                 if ($hasinline) {
167                     // If the default inline TeX delimiters \( \) are present, wrap each pair in nolink.
168                     $text = preg_replace('/\\\\\\([\S\s]*?\\\\\\)/u',
169                         '<span class="nolink">\0</span>', $text);
170                 }
171                 if ($hasdisplay) {
172                     // If default display TeX is used, wrap $$ $$ or \[ \] individually.
173                     $text = preg_replace('/\$\$[\S\s]*?\$\$|\\\\\\[[\S\s]*?\\\\\\]/u',
174                         '<span class="nolink">\0</span>', $text);
175                 }
176             }
177             return '<span class="filter_mathjaxloader_equation">' . $text . '</span>';
178         }
179         return $text;
180     }