MDL-43856 MathJax: Add a mathjax loader filter.

This commit is contained in:
Damyon Wiese 2013-11-20 16:47:16 +08:00
parent bc348632e1
commit 7f6753151e
15 changed files with 558 additions and 0 deletions

View File

@ -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;
}
}

View File

@ -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';

View File

@ -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.

View File

@ -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);
}

View File

@ -0,0 +1,3 @@
.jsenabled #MathJax_ZoomFrame {
position: absolute;
}

View File

@ -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';

View File

@ -0,0 +1,46 @@
YUI.add('moodle-filter_mathjax-loader', function (Y, NAME) {
// 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_mathjax
* @copyright 2014 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
M.filter_mathjax = M.filter_mathjax || {
init : function(params) {
// Add an inline configuration tag to the head.
var config = Y.Node.create('<script type="text/x-mathjax-config"></script>');
config.setHTML(params.mathjaxconfig);
Y.one('head').append(config);
// Load the mathjax library.
Y.Get.js(params.mathjaxurl, function() {
// Tell mathjax to call back for the language files.
debugger;
MathJax.Localization.addTranslation(params.lang,null,{
menuTitle: params.langdescription,
directory: M.cfg.wwwroot + "/filter/mathjax/language.php?lang="
});
});
}
};
}, '@VERSION@', {"requires": ["get", "node"]});

View File

@ -0,0 +1 @@
YUI.add("moodle-filter_mathjax-loader",function(e,t){M.filter_mathjax=M.filter_mathjax||{init:function(t){var n=e.Node.create('<script type="text/x-mathjax-config"></script>');n.setHTML(t.mathjaxconfig),e.one("head").append(n),e.Get.js(t.mathjaxurl,function(){debugger;MathJax.Localization.addTranslation(t.lang,null,{menuTitle:t.langdescription,directory:M.cfg.wwwroot+"/filter/mathjax/language.php?lang="})})}}},"@VERSION@",{requires:["get","node"]});

View File

@ -0,0 +1,46 @@
YUI.add('moodle-filter_mathjax-loader', function (Y, NAME) {
// 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_mathjax
* @copyright 2014 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
M.filter_mathjax = M.filter_mathjax || {
init : function(params) {
// Add an inline configuration tag to the head.
var config = Y.Node.create('<script type="text/x-mathjax-config"></script>');
config.setHTML(params.mathjaxconfig);
Y.one('head').append(config);
// Load the mathjax library.
Y.Get.js(params.mathjaxurl, function() {
// Tell mathjax to call back for the language files.
debugger;
MathJax.Localization.addTranslation(params.lang,null,{
menuTitle: params.langdescription,
directory: M.cfg.wwwroot + "/filter/mathjax/language.php?lang="
});
});
}
};
}, '@VERSION@', {"requires": ["get", "node"]});

View File

@ -0,0 +1,45 @@
YUI.add('moodle-filter_mathjaxloader-loader', function (Y, NAME) {
// 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();
}
};
}, '@VERSION@', {"requires": ["mathjax"]});

View File

@ -0,0 +1 @@
YUI.add("moodle-filter_mathjaxloader-loader",function(e,t){M.filter_mathjaxloader=M.filter_mathjaxloader||{init:function(t){var n=document.createElement("script");n.type="text/x-mathjax-config",n[window.opera?"innerHTML":"text"]=t.mathjaxconfig,document.getElementsByTagName("head")[0].appendChild(n),MathJax.Localization.setLocale(t.lang),e.all(".filter_mathjaxloader_equation").each(function(e){MathJax.Hub.Queue(["Typeset",MathJax.Hub,e.getDOMNode()])}),MathJax.Hub.Configured()}}},"@VERSION@",{requires:["mathjax"]});

View File

@ -0,0 +1,45 @@
YUI.add('moodle-filter_mathjaxloader-loader', function (Y, NAME) {
// 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();
}
};
}, '@VERSION@', {"requires": ["mathjax"]});

View File

@ -0,0 +1,10 @@
{
"name": "moodle-filter_mathjaxloader-loader",
"builds": {
"moodle-filter_mathjaxloader-loader": {
"jsfiles": [
"loader.js"
]
}
}
}

View File

@ -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();
}
};

View File

@ -0,0 +1,7 @@
{
"moodle-filter_mathjaxloader-loader": {
"requires": [
"mathjax"
]
}
}