2004-02-18 02:15:00 +00:00
|
|
|
<?php
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
|
|
|
|
* Contain everything related to <math> </math> parsing
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
* @file
|
|
|
|
|
* @ingroup Parser
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2004-04-22 08:51:04 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
|
|
|
|
* Takes LaTeX fragments, sends them to a helper program (texvc) for rendering
|
|
|
|
|
* to rasterized PNG and HTML and MathML approximations. An appropriate
|
|
|
|
|
* rendering form is picked and returned.
|
2006-01-07 13:09:30 +00:00
|
|
|
*
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
* @author Tomasz Wegrzanowski, with additions by Brion Vibber (2003, 2004)
|
|
|
|
|
* @ingroup Parser
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2004-04-22 08:51:04 +00:00
|
|
|
class MathRenderer {
|
|
|
|
|
var $mode = MW_MATH_MODERN;
|
2004-08-22 17:24:50 +00:00
|
|
|
var $tex = '';
|
|
|
|
|
var $inputhash = '';
|
|
|
|
|
var $hash = '';
|
|
|
|
|
var $html = '';
|
|
|
|
|
var $mathml = '';
|
2004-04-22 08:51:04 +00:00
|
|
|
var $conservativeness = 0;
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2007-07-13 17:25:06 +00:00
|
|
|
function __construct( $tex, $params=array() ) {
|
2004-04-22 08:51:04 +00:00
|
|
|
$this->tex = $tex;
|
2007-07-13 17:25:06 +00:00
|
|
|
$this->params = $params;
|
2004-04-22 08:51:04 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
function setOutputMode( $mode ) {
|
|
|
|
|
$this->mode = $mode;
|
2004-01-11 23:14:20 +00:00
|
|
|
}
|
2003-08-30 10:04:59 +00:00
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
function render() {
|
2005-11-02 23:14:33 +00:00
|
|
|
global $wgTmpDirectory, $wgInputEncoding;
|
2009-11-30 18:42:16 +00:00
|
|
|
global $wgTexvc, $wgMathCheckFiles, $wgTexvcBackgroundColor;
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
if( $this->mode == MW_MATH_SOURCE ) {
|
|
|
|
|
# No need to render or parse anything more!
|
2004-06-07 17:19:05 +00:00
|
|
|
return ('$ '.htmlspecialchars( $this->tex ).' $');
|
2004-03-26 16:47:12 +00:00
|
|
|
}
|
2007-01-06 18:46:08 +00:00
|
|
|
if( $this->tex == '' ) {
|
|
|
|
|
return; # bug 8372
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
if( !$this->_recall() ) {
|
2009-09-14 21:58:41 +00:00
|
|
|
if( $wgMathCheckFiles ) {
|
|
|
|
|
# Ensure that the temp and output directories are available before continuing...
|
|
|
|
|
if( !file_exists( $wgTmpDirectory ) ) {
|
|
|
|
|
if( !wfMkdirParents( $wgTmpDirectory ) ) {
|
|
|
|
|
return $this->_error( 'math_bad_tmpdir' );
|
|
|
|
|
}
|
|
|
|
|
} elseif( !is_dir( $wgTmpDirectory ) || !is_writable( $wgTmpDirectory ) ) {
|
2004-08-22 17:24:50 +00:00
|
|
|
return $this->_error( 'math_bad_tmpdir' );
|
2004-04-22 08:51:04 +00:00
|
|
|
}
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-06-18 05:09:27 +00:00
|
|
|
if( function_exists( 'is_executable' ) && !is_executable( $wgTexvc ) ) {
|
2004-08-22 17:24:50 +00:00
|
|
|
return $this->_error( 'math_notexvc' );
|
2004-04-22 08:51:04 +00:00
|
|
|
}
|
2008-09-17 12:36:44 +00:00
|
|
|
$cmd = $wgTexvc . ' ' .
|
|
|
|
|
escapeshellarg( $wgTmpDirectory ).' '.
|
|
|
|
|
escapeshellarg( $wgTmpDirectory ).' '.
|
|
|
|
|
escapeshellarg( $this->tex ).' '.
|
2009-11-30 18:42:16 +00:00
|
|
|
escapeshellarg( $wgInputEncoding ).' '.
|
|
|
|
|
escapeshellarg( $wgTexvcBackgroundColor );
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-06-18 05:09:27 +00:00
|
|
|
if ( wfIsWindows() ) {
|
|
|
|
|
# Invoke it within cygwin sh, because texvc expects sh features in its default shell
|
2008-09-17 12:36:44 +00:00
|
|
|
$cmd = 'sh -c ' . wfEscapeShellArg( $cmd );
|
2006-01-07 13:09:30 +00:00
|
|
|
}
|
2005-06-18 05:09:27 +00:00
|
|
|
|
|
|
|
|
wfDebug( "TeX: $cmd\n" );
|
2004-04-22 08:51:04 +00:00
|
|
|
$contents = `$cmd`;
|
2005-06-18 05:09:27 +00:00
|
|
|
wfDebug( "TeX output:\n $contents\n---\n" );
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
if (strlen($contents) == 0) {
|
2004-08-22 17:24:50 +00:00
|
|
|
return $this->_error( 'math_unknown_error' );
|
2004-04-22 08:51:04 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
$retval = substr ($contents, 0, 1);
|
2006-06-26 15:50:03 +00:00
|
|
|
$errmsg = '';
|
2004-08-22 17:24:50 +00:00
|
|
|
if (($retval == 'C') || ($retval == 'M') || ($retval == 'L')) {
|
2006-11-29 11:43:58 +00:00
|
|
|
if ($retval == 'C') {
|
2004-04-22 08:51:04 +00:00
|
|
|
$this->conservativeness = 2;
|
2006-11-29 11:43:58 +00:00
|
|
|
} else if ($retval == 'M') {
|
2004-04-22 08:51:04 +00:00
|
|
|
$this->conservativeness = 1;
|
2006-11-29 11:43:58 +00:00
|
|
|
} else {
|
2004-04-22 08:51:04 +00:00
|
|
|
$this->conservativeness = 0;
|
2006-11-29 11:43:58 +00:00
|
|
|
}
|
2004-04-22 08:51:04 +00:00
|
|
|
$outdata = substr ($contents, 33);
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
$i = strpos($outdata, "\000");
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
$this->html = substr($outdata, 0, $i);
|
|
|
|
|
$this->mathml = substr($outdata, $i+1);
|
2004-08-22 17:24:50 +00:00
|
|
|
} else if (($retval == 'c') || ($retval == 'm') || ($retval == 'l')) {
|
2004-04-22 08:51:04 +00:00
|
|
|
$this->html = substr ($contents, 33);
|
2006-11-29 11:43:58 +00:00
|
|
|
if ($retval == 'c') {
|
2004-04-22 08:51:04 +00:00
|
|
|
$this->conservativeness = 2;
|
2006-11-29 11:43:58 +00:00
|
|
|
} else if ($retval == 'm') {
|
2004-04-22 08:51:04 +00:00
|
|
|
$this->conservativeness = 1;
|
2006-11-29 11:43:58 +00:00
|
|
|
} else {
|
2004-04-22 08:51:04 +00:00
|
|
|
$this->conservativeness = 0;
|
2006-11-29 11:43:58 +00:00
|
|
|
}
|
2009-12-11 21:07:27 +00:00
|
|
|
$this->mathml = null;
|
2004-08-22 17:24:50 +00:00
|
|
|
} else if ($retval == 'X') {
|
2009-12-11 21:07:27 +00:00
|
|
|
$this->html = null;
|
2004-04-22 08:51:04 +00:00
|
|
|
$this->mathml = substr ($contents, 33);
|
|
|
|
|
$this->conservativeness = 0;
|
2004-08-22 17:24:50 +00:00
|
|
|
} else if ($retval == '+') {
|
2009-12-11 21:07:27 +00:00
|
|
|
$this->html = null;
|
|
|
|
|
$this->mathml = null;
|
2004-04-22 08:51:04 +00:00
|
|
|
$this->conservativeness = 0;
|
|
|
|
|
} else {
|
|
|
|
|
$errbit = htmlspecialchars( substr($contents, 1) );
|
|
|
|
|
switch( $retval ) {
|
2007-09-27 17:33:59 +00:00
|
|
|
case 'E':
|
|
|
|
|
$errmsg = $this->_error( 'math_lexing_error', $errbit );
|
|
|
|
|
break;
|
|
|
|
|
case 'S':
|
|
|
|
|
$errmsg = $this->_error( 'math_syntax_error', $errbit );
|
|
|
|
|
break;
|
|
|
|
|
case 'F':
|
|
|
|
|
$errmsg = $this->_error( 'math_unknown_function', $errbit );
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
$errmsg = $this->_error( 'math_unknown_error', $errbit );
|
2004-04-22 08:51:04 +00:00
|
|
|
}
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2006-06-26 15:50:03 +00:00
|
|
|
if ( !$errmsg ) {
|
|
|
|
|
$this->hash = substr ($contents, 1, 32);
|
|
|
|
|
}
|
|
|
|
|
|
2006-11-29 11:43:58 +00:00
|
|
|
wfRunHooks( 'MathAfterTexvc', array( &$this, &$errmsg ) );
|
2006-06-26 15:50:03 +00:00
|
|
|
|
|
|
|
|
if ( $errmsg ) {
|
|
|
|
|
return $errmsg;
|
|
|
|
|
}
|
|
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
if (!preg_match("/^[a-f0-9]{32}$/", $this->hash)) {
|
2004-08-22 17:24:50 +00:00
|
|
|
return $this->_error( 'math_unknown_error' );
|
2004-04-22 08:51:04 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-11-04 02:33:50 +00:00
|
|
|
if( !file_exists( "$wgTmpDirectory/{$this->hash}.png" ) ) {
|
2004-08-22 17:24:50 +00:00
|
|
|
return $this->_error( 'math_image_error' );
|
2004-04-22 08:51:04 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2008-11-26 02:28:15 +00:00
|
|
|
if( filesize( "$wgTmpDirectory/{$this->hash}.png" ) == 0 ) {
|
|
|
|
|
return $this->_error( 'math_image_error' );
|
|
|
|
|
}
|
|
|
|
|
|
2005-11-04 02:33:50 +00:00
|
|
|
$hashpath = $this->_getHashPath();
|
|
|
|
|
if( !file_exists( $hashpath ) ) {
|
|
|
|
|
if( !@wfMkdirParents( $hashpath, 0755 ) ) {
|
|
|
|
|
return $this->_error( 'math_bad_output' );
|
|
|
|
|
}
|
|
|
|
|
} elseif( !is_dir( $hashpath ) || !is_writable( $hashpath ) ) {
|
|
|
|
|
return $this->_error( 'math_bad_output' );
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-11-04 02:33:50 +00:00
|
|
|
if( !rename( "$wgTmpDirectory/{$this->hash}.png", "$hashpath/{$this->hash}.png" ) ) {
|
|
|
|
|
return $this->_error( 'math_output_error' );
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
# Now save it back to the DB:
|
2005-04-12 04:03:21 +00:00
|
|
|
if ( !wfReadOnly() ) {
|
|
|
|
|
$outmd5_sql = pack('H32', $this->hash);
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-04-12 04:03:21 +00:00
|
|
|
$md5_sql = pack('H32', $this->md5); # Binary packed, not hex
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2005-04-12 04:03:21 +00:00
|
|
|
$dbw->replace( 'math', array( 'math_inputhash' ),
|
2006-01-07 13:09:30 +00:00
|
|
|
array(
|
2007-06-08 01:06:52 +00:00
|
|
|
'math_inputhash' => $dbw->encodeBlob($md5_sql),
|
|
|
|
|
'math_outputhash' => $dbw->encodeBlob($outmd5_sql),
|
2005-04-12 04:03:21 +00:00
|
|
|
'math_html_conservativeness' => $this->conservativeness,
|
|
|
|
|
'math_html' => $this->html,
|
|
|
|
|
'math_mathml' => $this->mathml,
|
2010-01-08 01:39:14 +00:00
|
|
|
), __METHOD__
|
2005-04-12 04:03:21 +00:00
|
|
|
);
|
|
|
|
|
}
|
2008-11-26 02:28:15 +00:00
|
|
|
|
|
|
|
|
// If we're replacing an older version of the image, make sure it's current.
|
|
|
|
|
global $wgUseSquid;
|
|
|
|
|
if ( $wgUseSquid ) {
|
|
|
|
|
$urls = array( $this->_mathImageUrl() );
|
|
|
|
|
$u = new SquidUpdate( $urls );
|
|
|
|
|
$u->doUpdate();
|
|
|
|
|
}
|
2004-03-26 16:47:12 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
return $this->_doRender();
|
2004-03-26 16:47:12 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-08-22 17:24:50 +00:00
|
|
|
function _error( $msg, $append = '' ) {
|
|
|
|
|
$mf = htmlspecialchars( wfMsg( 'math_failure' ) );
|
2004-04-22 08:51:04 +00:00
|
|
|
$errmsg = htmlspecialchars( wfMsg( $msg ) );
|
2006-02-03 06:36:05 +00:00
|
|
|
$source = htmlspecialchars( str_replace( "\n", ' ', $this->tex ) );
|
2004-04-22 08:51:04 +00:00
|
|
|
return "<strong class='error'>$mf ($errmsg$append): $source</strong>\n";
|
2004-01-11 23:14:20 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
function _recall() {
|
2009-09-14 21:58:41 +00:00
|
|
|
global $wgMathDirectory, $wgMathCheckFiles;
|
2004-07-10 03:09:26 +00:00
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
$this->md5 = md5( $this->tex );
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2006-01-07 13:09:30 +00:00
|
|
|
$rpage = $dbr->selectRow( 'math',
|
2004-07-10 03:09:26 +00:00
|
|
|
array( 'math_outputhash','math_html_conservativeness','math_html','math_mathml' ),
|
2007-06-08 01:06:52 +00:00
|
|
|
array( 'math_inputhash' => $dbr->encodeBlob(pack("H32", $this->md5))), # Binary packed, not hex
|
2010-01-08 01:39:14 +00:00
|
|
|
__METHOD__
|
2004-07-10 03:09:26 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if( $rpage !== false ) {
|
2004-04-22 08:51:04 +00:00
|
|
|
# Tailing 0x20s can get dropped by the database, add it back on if necessary:
|
2007-06-08 01:06:52 +00:00
|
|
|
$xhash = unpack( 'H32md5', $dbr->decodeBlob($rpage->math_outputhash) . " " );
|
2004-04-22 08:51:04 +00:00
|
|
|
$this->hash = $xhash ['md5'];
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
$this->conservativeness = $rpage->math_html_conservativeness;
|
|
|
|
|
$this->html = $rpage->math_html;
|
|
|
|
|
$this->mathml = $rpage->math_mathml;
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2008-11-26 02:13:40 +00:00
|
|
|
$filename = $this->_getHashPath() . "/{$this->hash}.png";
|
2009-09-14 21:58:41 +00:00
|
|
|
|
|
|
|
|
if( !$wgMathCheckFiles ) {
|
|
|
|
|
// Short-circuit the file existence & migration checks
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2008-11-26 02:13:40 +00:00
|
|
|
if( file_exists( $filename ) ) {
|
|
|
|
|
if( filesize( $filename ) == 0 ) {
|
|
|
|
|
// Some horrible error corrupted stuff :(
|
|
|
|
|
@unlink( $filename );
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2004-04-22 08:51:04 +00:00
|
|
|
}
|
2005-11-02 23:14:33 +00:00
|
|
|
|
|
|
|
|
if( file_exists( $wgMathDirectory . "/{$this->hash}.png" ) ) {
|
|
|
|
|
$hashpath = $this->_getHashPath();
|
|
|
|
|
|
|
|
|
|
if( !file_exists( $hashpath ) ) {
|
|
|
|
|
if( !@wfMkdirParents( $hashpath, 0755 ) ) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
} elseif( !is_dir( $hashpath ) || !is_writable( $hashpath ) ) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if ( function_exists( "link" ) ) {
|
|
|
|
|
return link ( $wgMathDirectory . "/{$this->hash}.png",
|
|
|
|
|
$hashpath . "/{$this->hash}.png" );
|
|
|
|
|
} else {
|
|
|
|
|
return rename ( $wgMathDirectory . "/{$this->hash}.png",
|
|
|
|
|
$hashpath . "/{$this->hash}.png" );
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
# Missing from the database and/or the render cache
|
|
|
|
|
return false;
|
2003-08-30 10:04:59 +00:00
|
|
|
}
|
|
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
|
|
|
|
* Select among PNG, HTML, or MathML output depending on
|
|
|
|
|
*/
|
2004-04-22 08:51:04 +00:00
|
|
|
function _doRender() {
|
|
|
|
|
if( $this->mode == MW_MATH_MATHML && $this->mathml != '' ) {
|
2007-07-13 17:25:06 +00:00
|
|
|
return Xml::tags( 'math',
|
|
|
|
|
$this->_attribs( 'math',
|
|
|
|
|
array( 'xmlns' => 'http://www.w3.org/1998/Math/MathML' ) ),
|
|
|
|
|
$this->mathml );
|
2004-04-22 08:51:04 +00:00
|
|
|
}
|
|
|
|
|
if (($this->mode == MW_MATH_PNG) || ($this->html == '') ||
|
|
|
|
|
(($this->mode == MW_MATH_SIMPLE) && ($this->conservativeness != 2)) ||
|
|
|
|
|
(($this->mode == MW_MATH_MODERN || $this->mode == MW_MATH_MATHML) && ($this->conservativeness == 0))) {
|
|
|
|
|
return $this->_linkToMathImage();
|
|
|
|
|
} else {
|
2007-07-13 17:25:06 +00:00
|
|
|
return Xml::tags( 'span',
|
|
|
|
|
$this->_attribs( 'span',
|
|
|
|
|
array( 'class' => 'texhtml' ) ),
|
|
|
|
|
$this->html );
|
2004-04-22 08:51:04 +00:00
|
|
|
}
|
2004-01-11 23:14:20 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2007-07-13 17:25:06 +00:00
|
|
|
function _attribs( $tag, $defaults=array(), $overrides=array() ) {
|
|
|
|
|
$attribs = Sanitizer::validateTagAttributes( $this->params, $tag );
|
|
|
|
|
$attribs = Sanitizer::mergeAttributes( $defaults, $attribs );
|
|
|
|
|
$attribs = Sanitizer::mergeAttributes( $attribs, $overrides );
|
|
|
|
|
return $attribs;
|
|
|
|
|
}
|
2004-01-11 23:14:20 +00:00
|
|
|
|
2004-04-22 08:51:04 +00:00
|
|
|
function _linkToMathImage() {
|
2008-11-26 02:28:15 +00:00
|
|
|
$url = $this->_mathImageUrl();
|
2007-07-13 17:25:06 +00:00
|
|
|
|
|
|
|
|
return Xml::element( 'img',
|
|
|
|
|
$this->_attribs(
|
|
|
|
|
'img',
|
|
|
|
|
array(
|
|
|
|
|
'class' => 'tex',
|
|
|
|
|
'alt' => $this->tex ),
|
|
|
|
|
array(
|
|
|
|
|
'src' => $url ) ) );
|
2004-01-11 23:14:20 +00:00
|
|
|
}
|
2003-08-30 10:04:59 +00:00
|
|
|
|
2008-11-26 02:28:15 +00:00
|
|
|
function _mathImageUrl() {
|
|
|
|
|
global $wgMathPath;
|
|
|
|
|
$dir = $this->_getHashSubPath();
|
2008-11-26 02:37:07 +00:00
|
|
|
return "$wgMathPath/$dir/{$this->hash}.png";
|
2008-11-26 02:28:15 +00:00
|
|
|
}
|
|
|
|
|
|
2005-11-02 23:14:33 +00:00
|
|
|
function _getHashPath() {
|
|
|
|
|
global $wgMathDirectory;
|
2008-11-26 02:28:15 +00:00
|
|
|
$path = $wgMathDirectory .'/' . $this->_getHashSubPath();
|
2005-11-04 02:33:50 +00:00
|
|
|
wfDebug( "TeX: getHashPath, hash is: $this->hash, path is: $path\n" );
|
|
|
|
|
return $path;
|
2005-11-02 23:14:33 +00:00
|
|
|
}
|
2008-11-26 02:28:15 +00:00
|
|
|
|
|
|
|
|
function _getHashSubPath() {
|
|
|
|
|
return substr($this->hash, 0, 1)
|
|
|
|
|
.'/'. substr($this->hash, 1, 1)
|
|
|
|
|
.'/'. substr($this->hash, 2, 1);
|
|
|
|
|
}
|
2006-06-01 08:19:02 +00:00
|
|
|
|
2007-07-13 17:25:06 +00:00
|
|
|
public static function renderMath( $tex, $params=array() ) {
|
2006-06-06 10:00:53 +00:00
|
|
|
global $wgUser;
|
2007-07-13 17:25:06 +00:00
|
|
|
$math = new MathRenderer( $tex, $params );
|
2006-06-06 10:00:53 +00:00
|
|
|
$math->setOutputMode( $wgUser->getOption('math'));
|
|
|
|
|
return $math->render();
|
|
|
|
|
}
|
2003-08-30 10:04:59 +00:00
|
|
|
}
|