MDL-43856 MathJax: Add a mathjax loader filter.
[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 lazy_init() {
98         global $CFG, $PAGE;
99         // This only requires execution once per request.
100         static $jsinitialised = false;
102         if (empty($jsinitialised)) {
103             if (strpos($CFG->httpswwwroot, 'https:') === 0) {
104                 $url = get_config('filter_mathjaxloader', 'httpsurl');
105             } else {
106                 $url = get_config('filter_mathjaxloader', 'httpurl');
107             }
108             $lang = $this->map_language_code(current_language());
109             $url = new moodle_url($url, array('delayStartupUntil' => 'configured'));
111             $moduleconfig = array(
112                 'name' => 'mathjax',
113                 'fullpath' => $url
114             );
116             $PAGE->requires->js_module($moduleconfig);
118             $config = get_config('filter_mathjaxloader', 'mathjaxconfig');
120             $params = array('mathjaxconfig' => $config, 'lang' => $lang);
122             $PAGE->requires->yui_module('moodle-filter_mathjaxloader-loader', 'M.filter_mathjaxloader.init', array($params));
124             $jsinitialised = true;
125         }
126     }
128     /*
129      * This function wraps the filtered text in a span, that mathjaxloader is configured to process.
130      *
131      * @param string $text The text to filter.
132      * @param array $options The filter options.
133      */
134     public function filter($text, array $options = array()) {
135         // This replaces <tex> blah </tex> syntax with [tex] blah [/tex] syntax
136         // because MathJax cannot handle html tags as delimiters.
138         $text = preg_replace('|<(/?) *tex( [^>]*)?>|u', '[\1tex]', $text);
139         if (strpos($text, '$$') !== false || strpos($text, '\\[') !== false || strpos($text, '[tex]') !== false) {
140             // Only call init if there is at least one equation on the page.
141             $this->lazy_init();
142             return '<span class="filter_mathjaxloader_equation">' . $text . '</span>';
143         }
144         return $text;
145     }