MDL-43856 MathJax: Add a mathjax loader filter.
authorDamyon Wiese <damyon@moodle.com>
Wed, 20 Nov 2013 08:47:16 +0000 (16:47 +0800)
committerDamyon Wiese <damyon@moodle.com>
Thu, 3 Apr 2014 06:36:16 +0000 (14:36 +0800)
15 files changed:
filter/mathjaxloader/filter.php [new file with mode: 0644]
filter/mathjaxloader/lang/en/filter_mathjaxloader.php [new file with mode: 0644]
filter/mathjaxloader/readme_moodle.txt [new file with mode: 0644]
filter/mathjaxloader/settings.php [new file with mode: 0644]
filter/mathjaxloader/styles.css [new file with mode: 0644]
filter/mathjaxloader/version.php [new file with mode: 0644]
filter/mathjaxloader/yui/build/moodle-filter_mathjax-loader/moodle-filter_mathjax-loader-debug.js [new file with mode: 0644]
filter/mathjaxloader/yui/build/moodle-filter_mathjax-loader/moodle-filter_mathjax-loader-min.js [new file with mode: 0644]
filter/mathjaxloader/yui/build/moodle-filter_mathjax-loader/moodle-filter_mathjax-loader.js [new file with mode: 0644]
filter/mathjaxloader/yui/build/moodle-filter_mathjaxloader-loader/moodle-filter_mathjaxloader-loader-debug.js [new file with mode: 0644]
filter/mathjaxloader/yui/build/moodle-filter_mathjaxloader-loader/moodle-filter_mathjaxloader-loader-min.js [new file with mode: 0644]
filter/mathjaxloader/yui/build/moodle-filter_mathjaxloader-loader/moodle-filter_mathjaxloader-loader.js [new file with mode: 0644]
filter/mathjaxloader/yui/src/loader/build.json [new file with mode: 0644]
filter/mathjaxloader/yui/src/loader/js/loader.js [new file with mode: 0644]
filter/mathjaxloader/yui/src/loader/meta/loader.json [new file with mode: 0644]

diff --git a/filter/mathjaxloader/filter.php b/filter/mathjaxloader/filter.php
new file mode 100644 (file)
index 0000000..c0248fe
--- /dev/null
@@ -0,0 +1,146 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This filter provides automatic support for MathJax
+ *
+ * @package    filter_mathjaxloader
+ * @copyright  2013 Damyon Wiese (damyon@moodle.com)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Mathjax filtering
+ */
+class filter_mathjaxloader extends moodle_text_filter {
+
+    /*
+     * Perform a mapping of the moodle language code to the equivalent for MathJax.
+     *
+     * @param string $moodlelangcode - The moodle language code - e.g. en_pirate
+     * @return string The MathJax language code.
+     */
+    public function map_language_code($moodlelangcode) {
+        $mathjaxlangcodes = array('br',
+                                  'cdo',
+                                  'cs',
+                                  'da',
+                                  'de',
+                                  'en',
+                                  'eo',
+                                  'es',
+                                  'fa',
+                                  'fi',
+                                  'fr',
+                                  'gl',
+                                  'he',
+                                  'ia',
+                                  'it',
+                                  'ja',
+                                  'ko',
+                                  'lb',
+                                  'mk',
+                                  'nl',
+                                  'oc',
+                                  'pl',
+                                  'pt',
+                                  'pt-br',
+                                  'ru',
+                                  'sl',
+                                  'sv',
+                                  'tr',
+                                  'uk',
+                                  'zh-hans');
+        $exceptions = array('cz' => 'cs');
+
+        // First see if this is an exception.
+        if (isset($exceptions[$moodlelangcode])) {
+            $moodlelangcode = $exceptions[$moodlelangcode];
+        }
+
+        // Now look for an exact lang string match.
+        if (in_array($moodlelangcode, $mathjaxlangcodes)) {
+            return $moodlelangcode;
+        }
+
+        // Now try shortening the moodle lang string.
+        $moodlelangcode = preg_replace('/-.*/', '', $moodlelangcode);
+        // Look for a match on the shortened string.
+        if (in_array($moodlelangcode, $mathjaxlangcodes)) {
+            return $moodlelangcode;
+        }
+        // All failed - use english.
+        return 'en';
+    }
+
+    /*
+     * Add the javascript to enable mathjax processing on this page.
+     *
+     * @param moodle_page $page The current page.
+     * @param context $context The current context.
+     */
+    public function lazy_init() {
+        global $CFG, $PAGE;
+        // This only requires execution once per request.
+        static $jsinitialised = false;
+
+        if (empty($jsinitialised)) {
+            if (strpos($CFG->httpswwwroot, 'https:') === 0) {
+                $url = get_config('filter_mathjaxloader', 'httpsurl');
+            } else {
+                $url = get_config('filter_mathjaxloader', 'httpurl');
+            }
+            $lang = $this->map_language_code(current_language());
+            $url = new moodle_url($url, array('delayStartupUntil' => 'configured'));
+
+            $moduleconfig = array(
+                'name' => 'mathjax',
+                'fullpath' => $url
+            );
+
+            $PAGE->requires->js_module($moduleconfig);
+
+            $config = get_config('filter_mathjaxloader', 'mathjaxconfig');
+
+            $params = array('mathjaxconfig' => $config, 'lang' => $lang);
+
+            $PAGE->requires->yui_module('moodle-filter_mathjaxloader-loader', 'M.filter_mathjaxloader.init', array($params));
+
+            $jsinitialised = true;
+        }
+    }
+
+    /*
+     * This function wraps the filtered text in a span, that mathjaxloader is configured to process.
+     *
+     * @param string $text The text to filter.
+     * @param array $options The filter options.
+     */
+    public function filter($text, array $options = array()) {
+        // This replaces <tex> blah </tex> syntax with [tex] blah [/tex] syntax
+        // because MathJax cannot handle html tags as delimiters.
+
+        $text = preg_replace('|<(/?) *tex( [^>]*)?>|u', '[\1tex]', $text);
+        if (strpos($text, '$$') !== false || strpos($text, '\\[') !== false || strpos($text, '[tex]') !== false) {
+            // Only call init if there is at least one equation on the page.
+            $this->lazy_init();
+            return '<span class="filter_mathjaxloader_equation">' . $text . '</span>';
+        }
+        return $text;
+    }
+}
diff --git a/filter/mathjaxloader/lang/en/filter_mathjaxloader.php b/filter/mathjaxloader/lang/en/filter_mathjaxloader.php
new file mode 100644 (file)
index 0000000..3327778
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Strings for component 'filter_mathjax', language 'en'.
+ *
+ * Note: use filter/mathjax/cli/update_lang_files.php script to import strings from upstream JS lang files.
+ *
+ * @package    filter_mathjax
+ * @copyright  1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+
+//== Custom Moodle strings that are not part of upstream MathJax ==
+$string['filtername'] = 'MathJax';
+$string['httpurl'] = 'HTTP MathJax URL';
+$string['httpurl_help'] = 'Full URL to MathJax library. Used when the page is loaded via http.';
+$string['httpsurl'] = 'HTTP MathJax URL';
+$string['httpsurl_help'] = 'Full URL to MathJax library. Used when the page is loaded via https (secure). ';
+$string['localinstall'] = 'Local MathJax installation';
+$string['localinstall_help'] = 'The default MathJAX configuration uses the CDN version of MathJAX, but MathJAX can be installed locally if required. Some reasons this might be useful are to save on bandwidth - or because of local proxy restrictions. To use a local installation of MathJAX, first download the full MathJax library from http://www.mathjax.org/. Then install it on a web server. Finally update the MathJax filter settings httpurl and/or httpsurl to point to the local MathJax.js url.';
+$string['mathjaxsettings'] = 'MathJax configuration';
+$string['mathjaxsettings_desc'] = 'The default MathJAX configuration should be appropriate for most users, but MathJax is highly configurable and advanced users may want to provide a different configuration. More information on MathJax configuration options is available here: http://docs.mathjax.org/en/latest/options/index.html';
+
diff --git a/filter/mathjaxloader/readme_moodle.txt b/filter/mathjaxloader/readme_moodle.txt
new file mode 100644 (file)
index 0000000..76355a3
--- /dev/null
@@ -0,0 +1,15 @@
+Description of MathJAX library integration in Moodle
+=========================================================================================
+
+License: Apache 2.0
+Source: http://www.mathjax.org
+
+Moodle maintainer: Damyon Wiese
+
+=========================================================================================
+This library is not shipped with Moodle, but this filter is provided, which can be used to
+correctly load MathJax into a page from the CDN. Alternatively you can download the entire
+library and install it locally, then use this filter to load that local version.
+
+The only changes required to this filter to handle different MathJax versions is to update
+the CDN urls in filter.php - and update the list of language mappings - also in filter.php.
diff --git a/filter/mathjaxloader/settings.php b/filter/mathjaxloader/settings.php
new file mode 100644 (file)
index 0000000..fa9be8d
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * MathJAX filter settings
+ *
+ * @package    filter_mathjaxloader
+ * @copyright  2014 Damyon Wiese
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die;
+
+if ($ADMIN->fulltree) {
+    $item = new admin_setting_heading('filter_mathjaxloader/localinstall',
+                                         new lang_string('localinstall', 'filter_mathjaxloader'),
+                                         new lang_string('localinstall_help', 'filter_mathjaxloader'));
+    $settings->add($item);
+
+    $item = new admin_setting_configtext('filter_mathjaxloader/httpurl',
+                                         new lang_string('httpurl', 'filter_mathjaxloader'),
+                                         new lang_string('httpurl_help', 'filter_mathjaxloader'),
+                                         'http://cdn.mathjax.org/mathjax/2.3-latest/MathJax.js',
+                                         PARAM_RAW);
+    $settings->add($item);
+
+    $item = new admin_setting_configtext('filter_mathjaxloader/httpsurl',
+                                         new lang_string('httpsurl', 'filter_mathjaxloader'),
+                                         new lang_string('httpsurl_help', 'filter_mathjaxloader'),
+                                         'https://c328740.ssl.cf1.rackcdn.com/mathjax/2.3-latest/MathJax.js',
+                                         PARAM_RAW);
+    $settings->add($item);
+
+    $default = '
+MathJax.Hub.Config({
+    config: ["MMLorHTML.js", "Safe.js"],
+    jax: ["input/TeX","input/MathML","output/HTML-CSS","output/NativeMML"],
+    extensions: ["tex2jax.js","mml2jax.js","MathMenu.js","MathZoom.js"],
+    TeX: {
+        extensions: ["AMSmath.js","AMSsymbols.js","noErrors.js","noUndefined.js"]
+    },
+    menuSettings: {
+        zoom: "Double-Click",
+        mpContext: true,
+        mpMouse: true
+    },
+    errorSettings: { message: ["!"] },
+    tex2jax: {
+        skipTags: ["script","noscript","style","textarea"],
+        inlineMath: [
+            ["\\\\(","\\\\)"],
+            ["$$","$$"],
+            ["\\\\[","\\\\]"]
+        ],
+        displayMath: [
+            ["[tex]","[/tex]"],
+        ],
+        balanceBraces: true,
+        preview: "TeX"
+    },
+    skipStartupTypeset: true,
+    messageStyle: "none"
+});
+';
+
+    $item = new admin_setting_configtextarea('filter_mathjaxloader/mathjaxconfig',
+                                             new lang_string('mathjaxsettings','filter_mathjaxloader'),
+                                             new lang_string('mathjaxsettings_desc', 'filter_mathjaxloader'),
+                                             $default);
+
+    $settings->add($item);
+
+}
diff --git a/filter/mathjaxloader/styles.css b/filter/mathjaxloader/styles.css
new file mode 100644 (file)
index 0000000..f095292
--- /dev/null
@@ -0,0 +1,3 @@
+.jsenabled #MathJax_ZoomFrame {
+    position: absolute;
+}
diff --git a/filter/mathjaxloader/version.php b/filter/mathjaxloader/version.php
new file mode 100644 (file)
index 0000000..666c4b8
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * MathJax filter version information
+ *
+ * @package    filter_mathjaxloader
+ * @copyright  2014 Damyon Wiese (damyon@moodle.com)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$plugin->version  = 2013110500;
+$plugin->requires = 2013110500;  // Requires this Moodle version
+$plugin->component= 'filter_mathjaxloader';
diff --git a/filter/mathjaxloader/yui/build/moodle-filter_mathjax-loader/moodle-filter_mathjax-loader-debug.js b/filter/mathjaxloader/yui/build/moodle-filter_mathjax-loader/moodle-filter_mathjax-loader-debug.js
new file mode 100644 (file)
index 0000000..a2df120
Binary files /dev/null and b/filter/mathjaxloader/yui/build/moodle-filter_mathjax-loader/moodle-filter_mathjax-loader-debug.js differ
diff --git a/filter/mathjaxloader/yui/build/moodle-filter_mathjax-loader/moodle-filter_mathjax-loader-min.js b/filter/mathjaxloader/yui/build/moodle-filter_mathjax-loader/moodle-filter_mathjax-loader-min.js
new file mode 100644 (file)
index 0000000..6970a0f
Binary files /dev/null and b/filter/mathjaxloader/yui/build/moodle-filter_mathjax-loader/moodle-filter_mathjax-loader-min.js differ
diff --git a/filter/mathjaxloader/yui/build/moodle-filter_mathjax-loader/moodle-filter_mathjax-loader.js b/filter/mathjaxloader/yui/build/moodle-filter_mathjax-loader/moodle-filter_mathjax-loader.js
new file mode 100644 (file)
index 0000000..a2df120
Binary files /dev/null and b/filter/mathjaxloader/yui/build/moodle-filter_mathjax-loader/moodle-filter_mathjax-loader.js differ
diff --git a/filter/mathjaxloader/yui/build/moodle-filter_mathjaxloader-loader/moodle-filter_mathjaxloader-loader-debug.js b/filter/mathjaxloader/yui/build/moodle-filter_mathjaxloader-loader/moodle-filter_mathjaxloader-loader-debug.js
new file mode 100644 (file)
index 0000000..8cea37e
Binary files /dev/null and b/filter/mathjaxloader/yui/build/moodle-filter_mathjaxloader-loader/moodle-filter_mathjaxloader-loader-debug.js differ
diff --git a/filter/mathjaxloader/yui/build/moodle-filter_mathjaxloader-loader/moodle-filter_mathjaxloader-loader-min.js b/filter/mathjaxloader/yui/build/moodle-filter_mathjaxloader-loader/moodle-filter_mathjaxloader-loader-min.js
new file mode 100644 (file)
index 0000000..1dffab9
Binary files /dev/null and b/filter/mathjaxloader/yui/build/moodle-filter_mathjaxloader-loader/moodle-filter_mathjaxloader-loader-min.js differ
diff --git a/filter/mathjaxloader/yui/build/moodle-filter_mathjaxloader-loader/moodle-filter_mathjaxloader-loader.js b/filter/mathjaxloader/yui/build/moodle-filter_mathjaxloader-loader/moodle-filter_mathjaxloader-loader.js
new file mode 100644 (file)
index 0000000..8cea37e
Binary files /dev/null and b/filter/mathjaxloader/yui/build/moodle-filter_mathjaxloader-loader/moodle-filter_mathjaxloader-loader.js differ
diff --git a/filter/mathjaxloader/yui/src/loader/build.json b/filter/mathjaxloader/yui/src/loader/build.json
new file mode 100644 (file)
index 0000000..b262702
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "name": "moodle-filter_mathjaxloader-loader",
+    "builds": {
+        "moodle-filter_mathjaxloader-loader": {
+            "jsfiles": [
+                "loader.js"
+            ]
+        }
+    }
+}
diff --git a/filter/mathjaxloader/yui/src/loader/js/loader.js b/filter/mathjaxloader/yui/src/loader/js/loader.js
new file mode 100644 (file)
index 0000000..92adb06
--- /dev/null
@@ -0,0 +1,40 @@
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Mathjax JS Loader.
+ *
+ * @package    filter_mathjaxloader
+ * @copyright  2014 Damyon Wiese  <damyon@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+M.filter_mathjaxloader = M.filter_mathjaxloader || {
+    init: function(params) {
+
+        // Add a js configuration object to the head.
+        // See "http://docs.mathjax.org/en/latest/dynamic.html#ajax-mathjax"
+        var script = document.createElement("script");
+        script.type = "text/x-mathjax-config";
+        script[(window.opera ? "innerHTML" : "text")] = params.mathjaxconfig;
+        document.getElementsByTagName("head")[0].appendChild(script);
+
+        MathJax.Localization.setLocale(params.lang);
+
+        Y.all('.filter_mathjaxloader_equation').each(function(node) {
+            MathJax.Hub.Queue(["Typeset",MathJax.Hub,node.getDOMNode()]);
+        });
+        MathJax.Hub.Configured();
+    }
+};
diff --git a/filter/mathjaxloader/yui/src/loader/meta/loader.json b/filter/mathjaxloader/yui/src/loader/meta/loader.json
new file mode 100644 (file)
index 0000000..a8ce196
--- /dev/null
@@ -0,0 +1,7 @@
+{
+    "moodle-filter_mathjaxloader-loader": {
+        "requires": [
+            "mathjax"
+        ]
+    }
+}