MDL-60209 mathjax: Use MathJax 2.7.2 by default
[moodle.git] / filter / mathjaxloader / filter.php
CommitLineData
7f675315
DW
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/>.
16
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 */
24
25defined('MOODLE_INTERNAL') || die();
26
27/**
28 * Mathjax filtering
29 */
30class filter_mathjaxloader extends moodle_text_filter {
31
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');
70
71 // First see if this is an exception.
72 if (isset($exceptions[$moodlelangcode])) {
73 $moodlelangcode = $exceptions[$moodlelangcode];
74 }
75
76 // Now look for an exact lang string match.
77 if (in_array($moodlelangcode, $mathjaxlangcodes)) {
78 return $moodlelangcode;
79 }
80
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 }
90
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 */
aaf6f1e8 97 public function setup($page, $context) {
7f675315
DW
98 // This only requires execution once per request.
99 static $jsinitialised = false;
100
101 if (empty($jsinitialised)) {
8ce58c99 102 $url = get_config('filter_mathjaxloader', 'httpsurl');
7f675315
DW
103 $lang = $this->map_language_code(current_language());
104 $url = new moodle_url($url, array('delayStartupUntil' => 'configured'));
105
106 $moduleconfig = array(
107 'name' => 'mathjax',
108 'fullpath' => $url
109 );
110
aaf6f1e8 111 $page->requires->js_module($moduleconfig);
7f675315
DW
112
113 $config = get_config('filter_mathjaxloader', 'mathjaxconfig');
3db9004f
DW
114 $wwwroot = new moodle_url('/');
115
116 $config = str_replace('{wwwroot}', $wwwroot->out(true), $config);
7f675315
DW
117
118 $params = array('mathjaxconfig' => $config, 'lang' => $lang);
119
aaf6f1e8 120 $page->requires->yui_module('moodle-filter_mathjaxloader-loader', 'M.filter_mathjaxloader.configure', array($params));
7f675315
DW
121
122 $jsinitialised = true;
123 }
124 }
125
126 /*
127 * This function wraps the filtered text in a span, that mathjaxloader is configured to process.
128 *
129 * @param string $text The text to filter.
130 * @param array $options The filter options.
131 */
132 public function filter($text, array $options = array()) {
aaf6f1e8
DW
133 global $PAGE;
134
cc90cedc 135 $legacy = get_config('filter_mathjaxloader', 'texfiltercompatibility');
894e2039 136 $extradelimiters = explode(',', get_config('filter_mathjaxloader', 'additionaldelimiters'));
cc90cedc
DW
137 if ($legacy) {
138 // This replaces any of the tex filter maths delimiters with the default for inline maths in MathJAX "\( blah \)".
441f94b2 139 // E.g. "<tex.*> blah </tex>".
cc90cedc 140 $text = preg_replace('|<(/?) *tex( [^>]*)?>|u', '[\1tex]', $text);
441f94b2 141 // E.g. "[tex.*] blah [/tex]".
cc90cedc
DW
142 $text = str_replace('[tex]', '\\(', $text);
143 $text = str_replace('[/tex]', '\\)', $text);
441f94b2 144 // E.g. "$$ blah $$".
6aec17bd 145 $text = preg_replace('|\$\$([\S\s]*?)\$\$|u', '\\(\1\\)', $text);
441f94b2 146 // E.g. "\[ blah \]".
cc90cedc
DW
147 $text = str_replace('\\[', '\\(', $text);
148 $text = str_replace('\\]', '\\)', $text);
149 }
150
151 $hasinline = strpos($text, '\\(') !== false && strpos($text, '\\)') !== false;
152 $hasdisplay = (strpos($text, '$$') !== false) ||
153 (strpos($text, '\\[') !== false && strpos($text, '\\]') !== false);
7f675315 154
894e2039
DW
155 $hasextra = false;
156
157 foreach ($extradelimiters as $extra) {
158 if ($extra && strpos($text, $extra) !== false) {
159 $hasextra = true;
160 break;
161 }
162 }
163 if ($hasinline || $hasdisplay || $hasextra) {
aaf6f1e8 164 $PAGE->requires->yui_module('moodle-filter_mathjaxloader-loader', 'M.filter_mathjaxloader.typeset');
638b4738 165 if ($hasextra) {
fa3f8147 166 // If custom dilimeters are used, wrap whole text to prevent autolinking.
f617ac5c 167 $text = '<span class="nolink">' . $text . '</span>';
638b4738
DT
168 } else {
169 if ($hasinline) {
fa3f8147 170 // If the default inline TeX delimiters \( \) are present, wrap each pair in nolink.
638b4738
DT
171 $text = preg_replace('/\\\\\\([\S\s]*?\\\\\\)/u',
172 '<span class="nolink">\0</span>', $text);
173 }
174 if ($hasdisplay) {
fa3f8147 175 // If default display TeX is used, wrap $$ $$ or \[ \] individually.
638b4738
DT
176 $text = preg_replace('/\$\$[\S\s]*?\$\$|\\\\\\[[\S\s]*?\\\\\\]/u',
177 '<span class="nolink">\0</span>', $text);
178 }
179 }
180 return '<span class="filter_mathjaxloader_equation">' . $text . '</span>';
7f675315
DW
181 }
182 return $text;
183 }
184}