Math.php: Difference between revisions
From Knot Atlas
Jump to navigationJump to search
No edit summary |
m (Reverted edits by BositTazel (Talk); changed back to last version by Scott) |
||
(5 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
This is a modification of the original 1.4.7 version; hopefully it will not bother rerendering when the .png file is missing, but isn't immediately needed. This should allow deleting all or part of the cache directory, without touching the math table in the database. The .png files will only be recreated as needed, and html-able formulas will be pulled from the database without TeX having to be invoked. |
|||
Original mediawiki 1.4.7 version, after making the changes described in [http://meta.wikimedia.org/wiki/Help_talk:Formula#Maynard_Handley.27s_suggestions], in the section 'HOW TO MAKE FONT-SIZED PNGs'. |
|||
After correcting a minor syntax error, this seems to work... delete away! --[[User:Scott|Scott]] 04:20, 21 Sep 2005 (EDT) |
|||
<pre> |
<pre> |
||
<?php |
<?php |
||
Line 13: | Line 15: | ||
* |
* |
||
* by Tomasz Wegrzanowski, with additions by Brion Vibber (2003, 2004) |
* by Tomasz Wegrzanowski, with additions by Brion Vibber (2003, 2004) |
||
* and a modification by Scott Morrison (2005) |
|||
* |
* |
||
* @package MediaWiki |
* @package MediaWiki |
||
Line 177: | Line 180: | ||
$this->mathml = $rpage->math_mathml; |
$this->mathml = $rpage->math_mathml; |
||
# if we're not going to need the png, don't force a render if it's missing |
|||
⚫ | |||
if( $this->_pngNeeded() ) { |
|||
⚫ | |||
return true; |
|||
} |
|||
} else { |
|||
return true; |
return true; |
||
} |
} |
||
Line 185: | Line 193: | ||
return false; |
return false; |
||
} |
} |
||
/** |
|||
* Decide whether the png file will be needed. |
|||
*/ |
|||
function _pngNeeded() { |
|||
⚫ | |||
⚫ | |||
(($this->mode == MW_MATH_MODERN || $this->mode == MW_MATH_MATHML) && ($this->conservativeness == 0))) { |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
/** |
/** |
||
Line 193: | Line 214: | ||
return "<math xmlns='http://www.w3.org/1998/Math/MathML'>{$this->mathml}</math>"; |
return "<math xmlns='http://www.w3.org/1998/Math/MathML'>{$this->mathml}</math>"; |
||
} |
} |
||
if |
if ($this->_pngNeeded()) { |
||
⚫ | |||
⚫ | |||
return $this->_linkToMathImage(); |
return $this->_linkToMathImage(); |
||
} else { |
} else { |
||
Line 203: | Line 222: | ||
function _linkToMathImage() { |
function _linkToMathImage() { |
||
global $wgMathPath; |
|||
$url = htmlspecialchars( "$wgMathPath/{$this->hash}.png" ); |
|||
$alt = trim(str_replace("\n", ' ', htmlspecialchars( $this->tex ))); |
|||
return "<img class='tex' src=\"$url\" alt=\"$alt\" />"; |
|||
$wgGetTexImageHeightInEx = './math/getTexImageHeightInEx.sh'; |
|||
$cmd = $wgGetTexImageHeightInEx.' '. |
|||
wfEscapeShellArg( "$wgMathDirectory/{$this->hash}.png" ); |
|||
$heightInEx = chop(`$cmd`)."ex"; |
|||
return "<img class='tex' src=\"$url\" alt=\"$alt\" style=\"height:$heightInEx\" />"; |
|||
} |
} |
||
Latest revision as of 06:23, 19 December 2008
This is a modification of the original 1.4.7 version; hopefully it will not bother rerendering when the .png file is missing, but isn't immediately needed. This should allow deleting all or part of the cache directory, without touching the math table in the database. The .png files will only be recreated as needed, and html-able formulas will be pulled from the database without TeX having to be invoked.
After correcting a minor syntax error, this seems to work... delete away! --Scott 04:20, 21 Sep 2005 (EDT)
<?php /** * Contain everything related to <math> </math> parsing * @package MediaWiki */ /** * 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. * * by Tomasz Wegrzanowski, with additions by Brion Vibber (2003, 2004) * and a modification by Scott Morrison (2005) * * @package MediaWiki */ class MathRenderer { var $mode = MW_MATH_MODERN; var $tex = ''; var $inputhash = ''; var $hash = ''; var $html = ''; var $mathml = ''; var $conservativeness = 0; function MathRenderer( $tex ) { $this->tex = $tex; } function setOutputMode( $mode ) { $this->mode = $mode; } function render() { global $wgMathDirectory, $wgTmpDirectory, $wgInputEncoding; global $wgTexvc; $fname = 'MathRenderer::render'; if( $this->mode == MW_MATH_SOURCE ) { # No need to render or parse anything more! return ('$ '.htmlspecialchars( $this->tex ).' $'); } if( !$this->_recall() ) { # Ensure that the temp and output directories are available before continuing... if( !file_exists( $wgMathDirectory ) ) { if( !@mkdir( $wgMathDirectory ) ) { return $this->_error( 'math_bad_output' ); } } elseif( !is_dir( $wgMathDirectory ) || !is_writable( $wgMathDirectory ) ) { return $this->_error( 'math_bad_output' ); } if( !file_exists( $wgTmpDirectory ) ) { if( !@mkdir( $wgTmpDirectory ) ) { return $this->_error( 'math_bad_tmpdir' ); } } elseif( !is_dir( $wgTmpDirectory ) || !is_writable( $wgTmpDirectory ) ) { return $this->_error( 'math_bad_tmpdir' ); } if( !is_executable( $wgTexvc ) ) { return $this->_error( 'math_notexvc' ); } $cmd = $wgTexvc.' '. wfEscapeShellArg($wgTmpDirectory).' '. wfEscapeShellArg($wgMathDirectory).' '. wfEscapeShellArg($this->tex).' '. wfEscapeShellArg($wgInputEncoding); wfDebug( 'TeX: '.$cmd ); $contents = `$cmd`; if (strlen($contents) == 0) { return $this->_error( 'math_unknown_error' ); } $retval = substr ($contents, 0, 1); if (($retval == 'C') || ($retval == 'M') || ($retval == 'L')) { if ($retval == 'C') $this->conservativeness = 2; else if ($retval == 'M') $this->conservativeness = 1; else $this->conservativeness = 0; $outdata = substr ($contents, 33); $i = strpos($outdata, "\000"); $this->html = substr($outdata, 0, $i); $this->mathml = substr($outdata, $i+1); } else if (($retval == 'c') || ($retval == 'm') || ($retval == 'l')) { $this->html = substr ($contents, 33); if ($retval == 'c') $this->conservativeness = 2; else if ($retval == 'm') $this->conservativeness = 1; else $this->conservativeness = 0; $this->mathml = NULL; } else if ($retval == 'X') { $this->html = NULL; $this->mathml = substr ($contents, 33); $this->conservativeness = 0; } else if ($retval == '+') { $this->html = NULL; $this->mathml = NULL; $this->conservativeness = 0; } else { $errbit = htmlspecialchars( substr($contents, 1) ); switch( $retval ) { case 'E': return $this->_error( 'math_lexing_error', $errbit ); case 'S': return $this->_error( 'math_syntax_error', $errbit ); case 'F': return $this->_error( 'math_unknown_function', $errbit ); default: return $this->_error( 'math_unknown_error', $errbit ); } } $this->hash = substr ($contents, 1, 32); if (!preg_match("/^[a-f0-9]{32}$/", $this->hash)) { return $this->_error( 'math_unknown_error' ); } if( !file_exists( "$wgMathDirectory/{$this->hash}.png" ) ) { return $this->_error( 'math_image_error' ); } # Now save it back to the DB: if ( !wfReadOnly() ) { $outmd5_sql = pack('H32', $this->hash); $md5_sql = pack('H32', $this->md5); # Binary packed, not hex $dbw =& wfGetDB( DB_MASTER ); $dbw->replace( 'math', array( 'math_inputhash' ), array( 'math_inputhash' => $md5_sql, 'math_outputhash' => $outmd5_sql, 'math_html_conservativeness' => $this->conservativeness, 'math_html' => $this->html, 'math_mathml' => $this->mathml, ), $fname, array( 'IGNORE' ) ); } } return $this->_doRender(); } function _error( $msg, $append = '' ) { $mf = htmlspecialchars( wfMsg( 'math_failure' ) ); $munk = htmlspecialchars( wfMsg( 'math_unknown_error' ) ); $errmsg = htmlspecialchars( wfMsg( $msg ) ); $source = htmlspecialchars($this->tex); return "<strong class='error'>$mf ($errmsg$append): $source</strong>\n"; } function _recall() { global $wgMathDirectory; $fname = 'MathRenderer::_recall'; $this->md5 = md5( $this->tex ); $dbr =& wfGetDB( DB_SLAVE ); $rpage = $dbr->selectRow( 'math', array( 'math_outputhash','math_html_conservativeness','math_html','math_mathml' ), array( 'math_inputhash' => pack("H32", $this->md5)), # Binary packed, not hex $fname ); if( $rpage !== false ) { # Tailing 0x20s can get dropped by the database, add it back on if necessary: $xhash = unpack( 'H32md5', $rpage->math_outputhash . " " ); $this->hash = $xhash ['md5']; $this->conservativeness = $rpage->math_html_conservativeness; $this->html = $rpage->math_html; $this->mathml = $rpage->math_mathml; # if we're not going to need the png, don't force a render if it's missing if( $this->_pngNeeded() ) { if( file_exists( "$wgMathDirectory/{$this->hash}.png" ) ) { return true; } } else { return true; } } # Missing from the database and/or the render cache return false; } /** * Decide whether the png file will be needed. */ function _pngNeeded() { 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 true; } else { return false; } } /** * Select among PNG, HTML, or MathML output depending on */ function _doRender() { if( $this->mode == MW_MATH_MATHML && $this->mathml != '' ) { return "<math xmlns='http://www.w3.org/1998/Math/MathML'>{$this->mathml}</math>"; } if ($this->_pngNeeded()) { return $this->_linkToMathImage(); } else { return '<span class="texhtml">'.$this->html.'</span>'; } } function _linkToMathImage() { global $wgMathPath; $url = htmlspecialchars( "$wgMathPath/{$this->hash}.png" ); $alt = trim(str_replace("\n", ' ', htmlspecialchars( $this->tex ))); return "<img class='tex' src=\"$url\" alt=\"$alt\" />"; } } function renderMath( $tex ) { global $wgUser; $math = new MathRenderer( $tex ); $math->setOutputMode( $wgUser->getOption('math')); return $math->render(); } ?>