mirror of
https://github.com/moodle/moodle.git
synced 2025-05-15 04:36:13 +02:00
MDL-44925 Add SVG output option to TeX notation filter with PNG or MathJax for backup
This commit is contained in:
parent
5fd0df97c5
commit
a57a336fd3
@ -34,6 +34,8 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
require_once($CFG->libdir . '/classes/useragent.php');
|
||||
|
||||
/**
|
||||
* Create TeX image link.
|
||||
*
|
||||
@ -100,6 +102,7 @@ function filter_text_image($imagefile, $tex, $height, $width, $align, $alt) {
|
||||
$action = new popup_action('click', $link, 'popup', array('width'=>320,'height'=>240));
|
||||
}
|
||||
$output = $OUTPUT->action_link($link, $anchorcontents, $action, array('title'=>'TeX')); //TODO: the popups do not work when text caching is enabled!!
|
||||
$output = "<span class=\"MathJax_Preview\">$output</span><script type=\"math/tex\">$tex</script>";
|
||||
|
||||
return $output;
|
||||
}
|
||||
@ -197,6 +200,9 @@ class filter_tex extends moodle_text_filter {
|
||||
$DB->insert_record("cache_filters", $texcache, false);
|
||||
}
|
||||
$convertformat = get_config('filter_tex', 'convertformat');
|
||||
if ($convertformat == 'svg' && !core_useragent::supports_svg()) {
|
||||
$convertformat = 'png';
|
||||
}
|
||||
$filename = $md5.".{$convertformat}";
|
||||
$text = str_replace( $matches[0][$i], filter_text_image($filename, $texexp, 0, 0, $align, $alt), $text);
|
||||
}
|
||||
|
@ -23,13 +23,14 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['configconvertformat'] = 'If <i>latex</i>, <i>dvips</i> and <i>convert</i> are available, the images are created using the specified format. If it is not, mimeTeX will be used and it will create GIF images.';
|
||||
$string['convertformat'] = '<i>Convert</i> output format';
|
||||
$string['configconvertformat'] = 'If <i>latex</i> and <i>dvips</i> and are available, they are used to GIF or PNG images if <i>convert</i> is also available or if <i>dvisvgm</i> is available SVG images as specified. Otherwise <i>mimeTeX</i> will be used, and it will create GIF images.';
|
||||
$string['convertformat'] = 'Output image format';
|
||||
$string['latexpreamble'] = 'LaTeX preamble';
|
||||
$string['latexsettings'] = 'LaTeX renderer Settings';
|
||||
$string['filtername'] = 'TeX notation';
|
||||
$string['pathconvert'] = 'Path of <i>convert</i> binary';
|
||||
$string['pathdvips'] = 'Path of <i>dvips</i> binary';
|
||||
$string['pathdvisvgm'] = 'Path of <i>dvisvgm</i> binary';
|
||||
$string['pathlatex'] = 'Path of <i>latex</i> binary';
|
||||
$string['pathmimetex'] = 'Path of <i>mimetex</i> binary';
|
||||
$string['pathmimetexdesc'] = 'Moodle will use its own mimetex binary unless another valid path is specified.';
|
||||
|
@ -78,7 +78,7 @@
|
||||
/**
|
||||
* Render TeX string into gif/png
|
||||
* @param string $formula TeX formula
|
||||
* @param string $filename base of filename for output (no extension)
|
||||
* @param string $filename filename for output (including extension)
|
||||
* @param int $fontsize font size
|
||||
* @param int $density density value for .ps to .gif/.png conversion
|
||||
* @param string $background background color (e.g, #FFFFFF).
|
||||
@ -98,10 +98,14 @@
|
||||
$doc = $this->construct_latex_document( $formula, $fontsize );
|
||||
|
||||
// construct some file paths
|
||||
$convertformat = get_config('filter_tex', 'convertformat');
|
||||
if (!strpos($filename, ".{$convertformat}")) {
|
||||
$convertformat = 'png';
|
||||
}
|
||||
$filename = str_replace(".{$convertformat}", '', $filename);
|
||||
$tex = "{$this->temp_dir}/$filename.tex";
|
||||
$dvi = "{$this->temp_dir}/$filename.dvi";
|
||||
$ps = "{$this->temp_dir}/$filename.ps";
|
||||
$convertformat = get_config('filter_tex', 'convertformat');
|
||||
$img = "{$this->temp_dir}/$filename.{$convertformat}";
|
||||
|
||||
// turn the latex doc into a .tex file in the temp area
|
||||
@ -123,14 +127,19 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
// run convert on document (.ps to .gif/.png)
|
||||
// Run convert on document (.ps to .gif/.png) or run dvisvgm (.ps to .svg).
|
||||
if ($background) {
|
||||
$bg_opt = "-transparent \"$background\""; // Makes transparent background
|
||||
} else {
|
||||
$bg_opt = "";
|
||||
}
|
||||
$pathconvert = get_config('filter_tex', 'pathconvert');
|
||||
$command = "{$pathconvert} -density $density -trim $bg_opt $ps $img";
|
||||
if ($convertformat == 'svg') {
|
||||
$pathdvisvgm = get_config('filter_tex', 'pathdvisvgm');
|
||||
$command = "{$pathdvisvgm} -E $ps -o $img";
|
||||
} else {
|
||||
$pathconvert = get_config('filter_tex', 'pathconvert');
|
||||
$command = "{$pathconvert} -density $density -trim $bg_opt $ps $img";
|
||||
}
|
||||
if ($this->execute($command, $log )) {
|
||||
return false;
|
||||
}
|
||||
|
@ -127,13 +127,21 @@ function filter_tex_updatedcallback($name) {
|
||||
|
||||
$pathdvips = get_config('filter_tex', 'pathdvips');
|
||||
$pathconvert = get_config('filter_tex', 'pathconvert');
|
||||
$pathdvisvgm = get_config('filter_tex', 'pathdvisvgm');
|
||||
|
||||
if (!(is_file($pathlatex) && is_executable($pathlatex) &&
|
||||
is_file($pathdvips) && is_executable($pathdvips) &&
|
||||
is_file($pathconvert) && is_executable($pathconvert))) {
|
||||
// LaTeX, dvips or convert are not available, and mimetex can only produce GIFs so...
|
||||
set_config('convertformat', 'gif', 'filter_tex');
|
||||
$supportedformats = array('gif');
|
||||
if ((is_file($pathlatex) && is_executable($pathlatex)) &&
|
||||
(is_file($pathdvips) && is_executable($pathdvips))) {
|
||||
if (is_file($pathconvert) && is_executable($pathconvert)) {
|
||||
$supportedformats[] = 'png';
|
||||
}
|
||||
if (is_file($pathdvisvgm) && is_executable($pathdvisvgm)) {
|
||||
$supportedformats[] = 'svg';
|
||||
}
|
||||
}
|
||||
if (!in_array(get_config('filter_tex', 'convertformat'), $supportedformats)) {
|
||||
set_config('convertformat', array_pop($supportedformats), 'filter_tex');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,6 +33,9 @@ define('NO_MOODLE_COOKIES', true); // Because it interferes with caching
|
||||
|
||||
if (!file_exists($pathname)) {
|
||||
$convertformat = get_config('filter_tex', 'convertformat');
|
||||
if (strpos($image, '.png')) {
|
||||
$convertformat = 'png';
|
||||
}
|
||||
$md5 = str_replace(".{$convertformat}", '', $image);
|
||||
if ($texcache = $DB->get_record('cache_filters', array('filter'=>'tex', 'md5key'=>$md5))) {
|
||||
if (!file_exists($CFG->dataroot.'/filter/tex')) {
|
||||
@ -44,9 +47,9 @@ define('NO_MOODLE_COOKIES', true); // Because it interferes with caching
|
||||
$density = get_config('filter_tex', 'density');
|
||||
$background = get_config('filter_tex', 'latexbackground');
|
||||
$texexp = $texcache->rawtext; // the entities are now decoded before inserting to DB
|
||||
$latex_path = $latex->render($texexp, $md5, 12, $density, $background);
|
||||
if ($latex_path) {
|
||||
copy($latex_path, $pathname);
|
||||
$lateximage = $latex->render($texexp, $image, 12, $density, $background);
|
||||
if ($lateximage) {
|
||||
copy($lateximage, $pathname);
|
||||
$latex->clean_up($md5);
|
||||
|
||||
} else {
|
||||
|
@ -39,6 +39,7 @@ if ($ADMIN->fulltree) {
|
||||
if (PHP_OS=='Linux') {
|
||||
$default_filter_tex_pathlatex = "/usr/bin/latex";
|
||||
$default_filter_tex_pathdvips = "/usr/bin/dvips";
|
||||
$default_filter_tex_pathdvisvgm = "/usr/bin/dvisvgm";
|
||||
$default_filter_tex_pathconvert = "/usr/bin/convert";
|
||||
|
||||
} else if (PHP_OS=='Darwin') {
|
||||
@ -57,18 +58,20 @@ if ($ADMIN->fulltree) {
|
||||
} else {
|
||||
$default_filter_tex_pathlatex = '';
|
||||
$default_filter_tex_pathdvips = '';
|
||||
$default_filter_tex_pathdvisvgm = '';
|
||||
$default_filter_tex_pathconvert = '';
|
||||
}
|
||||
|
||||
$items[] = new admin_setting_configexecutable('filter_tex/pathlatex', get_string('pathlatex', 'filter_tex'), '', $default_filter_tex_pathlatex);
|
||||
$items[] = new admin_setting_configexecutable('filter_tex/pathdvips', get_string('pathdvips', 'filter_tex'), '', $default_filter_tex_pathdvips);
|
||||
$items[] = new admin_setting_configexecutable('filter_tex/pathconvert', get_string('pathconvert', 'filter_tex'), '', $default_filter_tex_pathconvert);
|
||||
$items[] = new admin_setting_configexecutable('filter_tex/pathdvisvgm', get_string('pathdvisvgm', 'filter_tex'), '', $default_filter_tex_pathdvisvgm);
|
||||
$items[] = new admin_setting_configexecutable('filter_tex/pathmimetex', get_string('pathmimetex', 'filter_tex'), get_string('pathmimetexdesc', 'filter_tex'), '');
|
||||
|
||||
// Even if we offer GIF and PNG formats here, in the update callback we check whether
|
||||
// all the paths actually point to executables. If they don't, we force the setting
|
||||
// Even if we offer GIF, PNG and SVG formats here, in the update callback we check whether
|
||||
// required paths actually point to executables. If they don't, we force the setting
|
||||
// to GIF, as that's the only format mimeTeX can produce.
|
||||
$formats = array('gif' => 'GIF', 'png' => 'PNG');
|
||||
$formats = array('gif' => 'GIF', 'png' => 'PNG', 'svg' => 'SVG');
|
||||
$items[] = new admin_setting_configselect('filter_tex/convertformat', get_string('convertformat', 'filter_tex'), get_string('configconvertformat', 'filter_tex'), 'gif', $formats);
|
||||
|
||||
foreach ($items as $item) {
|
||||
|
@ -199,31 +199,35 @@
|
||||
|
||||
// first check if it is likely to work at all
|
||||
$output .= "<h3>Checking executables</h3>\n";
|
||||
$executables_exist = true;
|
||||
$executablesexist = true;
|
||||
$pathlatex = get_config('filter_tex', 'pathlatex');
|
||||
if (is_file($pathlatex)) {
|
||||
$output .= "latex executable ($pathlatex) is readable<br />\n";
|
||||
}
|
||||
else {
|
||||
$executables_exist = false;
|
||||
} else {
|
||||
$executablesexist = false;
|
||||
$output .= "<b>Error:</b> latex executable ($pathlatex) is not readable<br />\n";
|
||||
}
|
||||
$pathdvips = get_config('filter_tex', 'pathdvips');
|
||||
if (is_file($pathdvips)) {
|
||||
$output .= "dvips executable ($pathdvips) is readable<br />\n";
|
||||
}
|
||||
else {
|
||||
$executables_exist = false;
|
||||
} else {
|
||||
$executablesexist = false;
|
||||
$output .= "<b>Error:</b> dvips executable ($pathdvips) is not readable<br />\n";
|
||||
}
|
||||
$pathconvert = get_config('filter_tex', 'pathconvert');
|
||||
if (is_file($pathconvert)) {
|
||||
$output .= "convert executable ($pathconvert) is readable<br />\n";
|
||||
}
|
||||
else {
|
||||
$executables_exist = false;
|
||||
} else {
|
||||
$executablesexist = false;
|
||||
$output .= "<b>Error:</b> convert executable ($pathconvert) is not readable<br />\n";
|
||||
}
|
||||
$pathdvisvgm = get_config('filter_tex', 'pathdvisvgm');
|
||||
if (is_file($pathdvisvgm)) {
|
||||
$output .= "dvisvgm executable ($pathdvisvgm) is readable<br />\n";
|
||||
} else {
|
||||
$executablesexist = false;
|
||||
$output .= "<b>Error:</b> dvisvgm executable ($pathdvisvgm) is not readable<br />\n";
|
||||
}
|
||||
|
||||
// knowing that it might work..
|
||||
$md5 = md5($expression);
|
||||
@ -255,13 +259,17 @@
|
||||
$cmd = "$pathdvips -E $dvi -o $ps";
|
||||
$output .= execute($cmd);
|
||||
|
||||
// step 3: convert command
|
||||
$cmd = "$pathconvert -density 240 -trim $ps $img ";
|
||||
// Step 3: Set convert or dvisvgm command.
|
||||
if ($convertformat == 'svg') {
|
||||
$cmd = "$pathdvisvgm -E $ps -o $img";
|
||||
} else {
|
||||
$cmd = "$pathconvert -density 240 -trim $ps $img ";
|
||||
}
|
||||
$output .= execute($cmd);
|
||||
|
||||
if (!$graphic) {
|
||||
echo $output;
|
||||
} else if (file_exists($img)){
|
||||
} else if (file_exists($img)) {
|
||||
send_file($img, "$md5.{$convertformat}");
|
||||
} else {
|
||||
echo "Error creating image, see command execution output for more details.";
|
||||
@ -338,7 +346,7 @@ searches the database cache_filters table to see if this TeX expression had been
|
||||
processed before. If not, it adds a DB entry for that expression. It then
|
||||
replaces the TeX expression by an <img src=".../filter/tex/pix.php...">
|
||||
tag. The filter/tex/pix.php script then searches the database to find an
|
||||
appropriate gif/png image file for that expression and to create one if it doesn't exist.
|
||||
appropriate gif/png/svg image file for that expression and to create one if it doesn't exist.
|
||||
It will then use either the LaTex/Ghostscript renderer (using external executables
|
||||
on your system) or the bundled Mimetex executable. The full Latex/Ghostscript
|
||||
renderer produces better results and is tried first.
|
||||
@ -349,7 +357,7 @@ you might try to fix them.</p>
|
||||
process this expression. Then the database entry for that expression contains
|
||||
a bad TeX expression in the rawtext field (usually blank). You can fix this
|
||||
by clicking on "Delete DB Entry"</li>
|
||||
<li>The TeX to gif/png image conversion process does not work.
|
||||
<li>The TeX to gif/png/svg image conversion process does not work.
|
||||
If paths are specified in the filter configuation screen for the three
|
||||
executables these will be tried first. Note that they still must be correctly
|
||||
installed and have the correct permissions. In particular make sure that you
|
||||
|
Loading…
x
Reference in New Issue
Block a user