X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FMath.php;h=d24f30d45d4d9a0c5f2a1f2d635526fb9a9ce6ef;hb=0731560daf69a64b30eafe37e68e4e415a938aee;hp=cbe2cc09be12e976b093cc42160a7c70df3855ad;hpb=ca3ee3e3a1fe98dc15e4e511df0995357214ef64;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Math.php b/includes/Math.php index cbe2cc09be..d24f30d45d 100644 --- a/includes/Math.php +++ b/includes/Math.php @@ -1,19 +1,25 @@ 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) + * + * @package MediaWiki + */ class MathRenderer { var $mode = MW_MATH_MODERN; - var $tex = ""; - var $inputhash = ""; - var $hash = ""; - var $html = ""; - var $mathml = ""; + var $tex = ''; + var $inputhash = ''; + var $hash = ''; + var $html = ''; + var $mathml = ''; var $conservativeness = 0; function MathRenderer( $tex ) { @@ -27,49 +33,57 @@ class MathRenderer { 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( $tex ).' $'); + 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" ); + return $this->_error( 'math_bad_output' ); } } elseif( !is_dir( $wgMathDirectory ) || !is_writable( $wgMathDirectory ) ) { - return $this->_error( "math_bad_output" ); + return $this->_error( 'math_bad_output' ); } if( !file_exists( $wgTmpDirectory ) ) { if( !@mkdir( $wgTmpDirectory ) ) { - return $this->_error( "math_bad_tmpdir" ); + return $this->_error( 'math_bad_tmpdir' ); } } elseif( !is_dir( $wgTmpDirectory ) || !is_writable( $wgTmpDirectory ) ) { - return $this->_error( "math_bad_tmpdir" ); + return $this->_error( 'math_bad_tmpdir' ); } - if( !is_executable( $wgTexvc ) ) { - return $this->_error( "math_notexvc" ); + if( function_exists( 'is_executable' ) && !is_executable( $wgTexvc ) ) { + return $this->_error( 'math_notexvc' ); } - $cmd = $wgTexvc." ". - escapeshellarg($wgTmpDirectory)." ". - escapeshellarg($wgMathDirectory)." ". - escapeshellarg($this->tex)." ". - escapeshellarg($wgInputEncoding); - wfDebug( "TeX: $cmd" ); + $cmd = $wgTexvc . ' ' . + escapeshellarg( $wgTmpDirectory ).' '. + escapeshellarg( $wgMathDirectory ).' '. + escapeshellarg( $this->tex ).' '. + escapeshellarg( $wgInputEncoding ); + + if ( wfIsWindows() ) { + # Invoke it within cygwin sh, because texvc expects sh features in its default shell + $cmd = 'sh -c ' . wfEscapeShellArg( $cmd ); + } + + wfDebug( "TeX: $cmd\n" ); $contents = `$cmd`; + wfDebug( "TeX output:\n $contents\n---\n" ); if (strlen($contents) == 0) { - return $this->_error( "math_unknown_error" ); + return $this->_error( 'math_unknown_error' ); } $retval = substr ($contents, 0, 1); - if (($retval == "C") || ($retval == "M") || ($retval == "L")) { - if ($retval == "C") + if (($retval == 'C') || ($retval == 'M') || ($retval == 'L')) { + if ($retval == 'C') $this->conservativeness = 2; - else if ($retval == "M") + else if ($retval == 'M') $this->conservativeness = 1; else $this->conservativeness = 0; @@ -79,67 +93,68 @@ class MathRenderer { $this->html = substr($outdata, 0, $i); $this->mathml = substr($outdata, $i+1); - - $sql_html = "'".wfStrencode($this->html)."'"; - $sql_mathml = "'".wfStrencode($this->mathml)."'"; - } else if (($retval == "c") || ($retval == "m") || ($retval == "l")) { + } else if (($retval == 'c') || ($retval == 'm') || ($retval == 'l')) { $this->html = substr ($contents, 33); - if ($retval == "c") + if ($retval == 'c') $this->conservativeness = 2; - else if ($retval == "m") + else if ($retval == 'm') $this->conservativeness = 1; else $this->conservativeness = 0; - $sql_html = "'".wfStrencode($this->html)."'"; - $this->mathml = ''; - $sql_mathml = 'NULL'; - } else if ($retval == "X") { - $outhtml = ''; + $this->mathml = NULL; + } else if ($retval == 'X') { + $this->html = NULL; $this->mathml = substr ($contents, 33); - $sql_html = 'NULL'; - $sql_mathml = "'".wfStrencode($this->mathml)."'"; $this->conservativeness = 0; - } else if ($retval == "+") { - $this->outhtml = ''; - $this->mathml = ''; - $sql_html = 'NULL'; - $sql_mathml = 'NULL'; + } 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 ); + 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" ); + return $this->_error( 'math_unknown_error' ); } if( !file_exists( "$wgMathDirectory/{$this->hash}.png" ) ) { - return $this->_error( "math_image_error" ); + return $this->_error( 'math_image_error' ); } # Now save it back to the DB: - $outmd5_sql = wfStrencode(pack("H32", $this->hash)); - - $md5_sql = wfStrencode( pack("H32", $this->md5) ); # Binary packed, not hex - $sql = "REPLACE INTO math VALUES ('".$md5_sql."', '".$outmd5_sql."', ".$this->conservativeness.", ".$sql_html.", ".$sql_mathml.")"; + 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' ) + ); + } - $res = wfQuery( $sql, DB_WRITE, "MathRenderer::render" ); - # we don't really care if it fails } return $this->_doRender(); } - function _error( $msg, $append = "" ) { - $mf = htmlspecialchars( wfMsg( "math_failure" ) ); - $munk = htmlspecialchars( wfMsg( "math_unknown_error" ) ); + function _error( $msg, $append = '' ) { + $mf = htmlspecialchars( wfMsg( 'math_failure' ) ); + $munk = htmlspecialchars( wfMsg( 'math_unknown_error' ) ); $errmsg = htmlspecialchars( wfMsg( $msg ) ); $source = htmlspecialchars($this->tex); return "$mf ($errmsg$append): $source\n"; @@ -147,16 +162,19 @@ class MathRenderer { function _recall() { global $wgMathDirectory; - + $fname = 'MathRenderer::_recall'; + $this->md5 = md5( $this->tex ); - - $md5_sql = wfStrencode( pack("H32", $this->md5) ); # Binary packed, not hex - $sql = "SELECT math_outputhash,math_html_conservativeness,math_html,math_mathml FROM math WHERE math_inputhash = '$md5_sql'"; - $res = wfQuery( $sql, DB_READ, "MathRenderer::_recall" ); - - if( $rpage = wfFetchObject ( $res ) ) { + $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 . " " ); + $xhash = unpack( 'H32md5', $rpage->math_outputhash . " " ); $this->hash = $xhash ['md5']; $this->conservativeness = $rpage->math_html_conservativeness; @@ -172,7 +190,9 @@ class MathRenderer { return false; } - # Select among PNG, HTML, or MathML output depending on + /** + * Select among PNG, HTML, or MathML output depending on + */ function _doRender() { if( $this->mode == MW_MATH_MATHML && $this->mathml != '' ) { return "{$this->mathml}"; @@ -182,14 +202,14 @@ class MathRenderer { (($this->mode == MW_MATH_MODERN || $this->mode == MW_MATH_MATHML) && ($this->conservativeness == 0))) { return $this->_linkToMathImage(); } else { - return $this->html; + return ''.$this->html.''; } } function _linkToMathImage() { global $wgMathPath; $url = htmlspecialchars( "$wgMathPath/{$this->hash}.png" ); - $alt = htmlspecialchars( $this->tex ); + $alt = trim(str_replace("\n", ' ', htmlspecialchars( $this->tex ))); return "\"$alt\""; } @@ -198,7 +218,7 @@ class MathRenderer { function renderMath( $tex ) { global $wgUser; $math = new MathRenderer( $tex ); - $math->setOutputMode( $wgUser->getOption("math")); + $math->setOutputMode( $wgUser->getOption('math')); return $math->render(); }