Merge branch 'MDL-61715-34' of https://github.com/lethevinh/moodle into MOODLE_34_STABLE
[moodle.git] / filter / mathjaxloader / filter.php
bloba6010bfbcadf22387e266373a9fb26f5c38aaf72
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.
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
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
25 defined('MOODLE_INTERNAL') || die();
27 /**
28 * Mathjax filtering
30 class filter_mathjaxloader extends moodle_text_filter {
33 * Perform a mapping of the moodle language code to the equivalent for MathJax.
35 * @param string $moodlelangcode - The moodle language code - e.g. en_pirate
36 * @return string The MathJax language code.
38 public function map_language_code($moodlelangcode) {
40 // List of language codes found in the MathJax/localization/ directory.
41 $mathjaxlangcodes = [
42 'ar', 'ast', 'bcc', 'bg', 'br', 'ca', 'cdo', 'ce', 'cs', 'cy', 'da', 'de', 'diq', 'en', 'eo', 'es', 'fa',
43 'fi', 'fr', 'gl', 'he', 'ia', 'it', 'ja', 'kn', 'ko', 'lb', 'lki', 'lt', 'mk', 'nl', 'oc', 'pl', 'pt',
44 'pt-br', 'qqq', 'ru', 'scn', 'sco', 'sk', 'sl', 'sv', 'th', 'tr', 'uk', 'vi', 'zh-hans', 'zh-hant'
47 // List of explicit mappings and known exceptions (moodle => mathjax).
48 $explicit = [
49 'cz' => 'cs',
50 'pt_br' => 'pt-br',
51 'zh_tw' => 'zh-hant',
52 'zh_cn' => 'zh-hans',
55 // If defined, explicit mapping takes the highest precedence.
56 if (isset($explicit[$moodlelangcode])) {
57 return $explicit[$moodlelangcode];
60 // If there is exact match, it will be probably right.
61 if (in_array($moodlelangcode, $mathjaxlangcodes)) {
62 return $moodlelangcode;
65 // Finally try to find the best matching mathjax pack.
66 $parts = explode('_', $moodlelangcode, 2);
67 if (in_array($parts[0], $mathjaxlangcodes)) {
68 return $parts[0];
71 // No more guessing, use English.
72 return 'en';
76 * Add the javascript to enable mathjax processing on this page.
78 * @param moodle_page $page The current page.
79 * @param context $context The current context.
81 public function setup($page, $context) {
82 // This only requires execution once per request.
83 static $jsinitialised = false;
85 if (empty($jsinitialised)) {
86 $url = get_config('filter_mathjaxloader', 'httpsurl');
87 $lang = $this->map_language_code(current_language());
88 $url = new moodle_url($url, array('delayStartupUntil' => 'configured'));
90 $moduleconfig = array(
91 'name' => 'mathjax',
92 'fullpath' => $url
95 $page->requires->js_module($moduleconfig);
97 $config = get_config('filter_mathjaxloader', 'mathjaxconfig');
98 $wwwroot = new moodle_url('/');
100 $config = str_replace('{wwwroot}', $wwwroot->out(true), $config);
102 $params = array('mathjaxconfig' => $config, 'lang' => $lang);
104 $page->requires->yui_module('moodle-filter_mathjaxloader-loader', 'M.filter_mathjaxloader.configure', array($params));
106 $jsinitialised = true;
111 * This function wraps the filtered text in a span, that mathjaxloader is configured to process.
113 * @param string $text The text to filter.
114 * @param array $options The filter options.
116 public function filter($text, array $options = array()) {
117 global $PAGE;
119 $legacy = get_config('filter_mathjaxloader', 'texfiltercompatibility');
120 $extradelimiters = explode(',', get_config('filter_mathjaxloader', 'additionaldelimiters'));
121 if ($legacy) {
122 // This replaces any of the tex filter maths delimiters with the default for inline maths in MathJAX "\( blah \)".
123 // E.g. "<tex.*> blah </tex>".
124 $text = preg_replace('|<(/?) *tex( [^>]*)?>|u', '[\1tex]', $text);
125 // E.g. "[tex.*] blah [/tex]".
126 $text = str_replace('[tex]', '\\(', $text);
127 $text = str_replace('[/tex]', '\\)', $text);
128 // E.g. "$$ blah $$".
129 $text = preg_replace('|\$\$([\S\s]*?)\$\$|u', '\\(\1\\)', $text);
130 // E.g. "\[ blah \]".
131 $text = str_replace('\\[', '\\(', $text);
132 $text = str_replace('\\]', '\\)', $text);
135 $hasinline = strpos($text, '\\(') !== false && strpos($text, '\\)') !== false;
136 $hasdisplay = (strpos($text, '$$') !== false) ||
137 (strpos($text, '\\[') !== false && strpos($text, '\\]') !== false);
139 $hasextra = false;
141 foreach ($extradelimiters as $extra) {
142 if ($extra && strpos($text, $extra) !== false) {
143 $hasextra = true;
144 break;
147 if ($hasinline || $hasdisplay || $hasextra) {
148 $PAGE->requires->yui_module('moodle-filter_mathjaxloader-loader', 'M.filter_mathjaxloader.typeset');
149 if ($hasextra) {
150 // If custom dilimeters are used, wrap whole text to prevent autolinking.
151 $text = '<span class="nolink">' . $text . '</span>';
152 } else {
153 if ($hasinline) {
154 // If the default inline TeX delimiters \( \) are present, wrap each pair in nolink.
155 $text = preg_replace('/\\\\\\([\S\s]*?\\\\\\)/u',
156 '<span class="nolink">\0</span>', $text);
158 if ($hasdisplay) {
159 // If default display TeX is used, wrap $$ $$ or \[ \] individually.
160 $text = preg_replace('/\$\$[\S\s]*?\$\$|\\\\\\[[\S\s]*?\\\\\\]/u',
161 '<span class="nolink">\0</span>', $text);
164 return '<span class="filter_mathjaxloader_equation">' . $text . '</span>';
166 return $text;