X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FMath.php;h=8cf9b8d897709a6f072dbe320beacfef2a474fcb;hb=480257da0d92ec759b93d14b3ea6476c47e2fc01;hp=88934e5f0c370f5ba52821370c5aaa46c17ccf5e;hpb=f88c771756c580442fe7ca2f84bcbb8067b77f57;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Math.php b/includes/Math.php index 88934e5f0c..8cf9b8d897 100644 --- a/includes/Math.php +++ b/includes/Math.php @@ -1,6 +1,8 @@ parsing + * @file + * @ingroup Parser */ /** @@ -8,8 +10,8 @@ * 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) - * + * @author Tomasz Wegrzanowski, with additions by Brion Vibber (2003, 2004) + * @ingroup Parser */ class MathRenderer { var $mode = MW_MATH_MODERN; @@ -20,8 +22,9 @@ class MathRenderer { var $mathml = ''; var $conservativeness = 0; - function __construct( $tex ) { + function __construct( $tex, $params=array() ) { $this->tex = $tex; + $this->params = $params; } function setOutputMode( $mode ) { @@ -30,8 +33,7 @@ class MathRenderer { function render() { global $wgTmpDirectory, $wgInputEncoding; - global $wgTexvc; - $fname = 'MathRenderer::render'; + global $wgTexvc, $wgMathCheckFiles, $wgTexvcBackgroundColor; if( $this->mode == MW_MATH_SOURCE ) { # No need to render or parse anything more! @@ -42,13 +44,15 @@ class MathRenderer { } if( !$this->_recall() ) { - # Ensure that the temp and output directories are available before continuing... - if( !file_exists( $wgTmpDirectory ) ) { - if( !@mkdir( $wgTmpDirectory ) ) { + 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 ) ) { return $this->_error( 'math_bad_tmpdir' ); } - } elseif( !is_dir( $wgTmpDirectory ) || !is_writable( $wgTmpDirectory ) ) { - return $this->_error( 'math_bad_tmpdir' ); } if( function_exists( 'is_executable' ) && !is_executable( $wgTexvc ) ) { @@ -58,7 +62,8 @@ class MathRenderer { escapeshellarg( $wgTmpDirectory ).' '. escapeshellarg( $wgTmpDirectory ).' '. escapeshellarg( $this->tex ).' '. - escapeshellarg( $wgInputEncoding ); + escapeshellarg( $wgInputEncoding ).' '. + escapeshellarg( $wgTexvcBackgroundColor ); if ( wfIsWindows() ) { # Invoke it within cygwin sh, because texvc expects sh features in its default shell @@ -98,22 +103,29 @@ class MathRenderer { } else { $this->conservativeness = 0; } - $this->mathml = NULL; + $this->mathml = null; } else if ($retval == 'X') { - $this->html = NULL; + $this->html = null; $this->mathml = substr ($contents, 33); $this->conservativeness = 0; } else if ($retval == '+') { - $this->html = NULL; - $this->mathml = NULL; + $this->html = null; + $this->mathml = null; $this->conservativeness = 0; } else { $errbit = htmlspecialchars( substr($contents, 1) ); switch( $retval ) { - case 'E': $errmsg = $this->_error( 'math_lexing_error', $errbit ); - case 'S': $errmsg = $this->_error( 'math_syntax_error', $errbit ); - case 'F': $errmsg = $this->_error( 'math_unknown_function', $errbit ); - default: $errmsg = $this->_error( 'math_unknown_error', $errbit ); + 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 ); } } @@ -135,6 +147,10 @@ class MathRenderer { return $this->_error( 'math_image_error' ); } + if( filesize( "$wgTmpDirectory/{$this->hash}.png" ) == 0 ) { + return $this->_error( 'math_image_error' ); + } + $hashpath = $this->_getHashPath(); if( !file_exists( $hashpath ) ) { if( !@wfMkdirParents( $hashpath, 0755 ) ) { @@ -157,15 +173,22 @@ class MathRenderer { $dbw = wfGetDB( DB_MASTER ); $dbw->replace( 'math', array( 'math_inputhash' ), array( - 'math_inputhash' => $md5_sql, - 'math_outputhash' => $outmd5_sql, + 'math_inputhash' => $dbw->encodeBlob($md5_sql), + 'math_outputhash' => $dbw->encodeBlob($outmd5_sql), 'math_html_conservativeness' => $this->conservativeness, 'math_html' => $this->html, 'math_mathml' => $this->mathml, - ), $fname, array( 'IGNORE' ) + ), __METHOD__ ); } - + + // 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(); + } } return $this->_doRender(); @@ -179,29 +202,40 @@ class MathRenderer { } function _recall() { - global $wgMathDirectory; - $fname = 'MathRenderer::_recall'; + global $wgMathDirectory, $wgMathCheckFiles; $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 + array( 'math_inputhash' => $dbr->encodeBlob(pack("H32", $this->md5))), # Binary packed, not hex + __METHOD__ ); 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', $dbr->decodeBlob($rpage->math_outputhash) . " " ); $this->hash = $xhash ['md5']; $this->conservativeness = $rpage->math_html_conservativeness; $this->html = $rpage->math_html; $this->mathml = $rpage->math_mathml; - if( file_exists( $this->_getHashPath() . "/{$this->hash}.png" ) ) { + $filename = $this->_getHashPath() . "/{$this->hash}.png"; + + if( !$wgMathCheckFiles ) { + // Short-circuit the file existence & migration checks return true; } + + if( file_exists( $filename ) ) { + if( filesize( $filename ) == 0 ) { + // Some horrible error corrupted stuff :( + @unlink( $filename ); + } else { + return true; + } + } if( file_exists( $wgMathDirectory . "/{$this->hash}.png" ) ) { $hashpath = $this->_getHashPath(); @@ -233,40 +267,66 @@ class MathRenderer { */ function _doRender() { if( $this->mode == MW_MATH_MATHML && $this->mathml != '' ) { - return "{$this->mathml}"; + return Xml::tags( 'math', + $this->_attribs( 'math', + array( 'xmlns' => 'http://www.w3.org/1998/Math/MathML' ) ), + $this->mathml ); } 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 { - return ''.$this->html.''; + return Xml::tags( 'span', + $this->_attribs( 'span', + array( 'class' => 'texhtml' ) ), + $this->html ); } } + 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; + } + function _linkToMathImage() { - global $wgMathPath; - $url = htmlspecialchars( "$wgMathPath/" . substr($this->hash, 0, 1) - .'/'. substr($this->hash, 1, 1) .'/'. substr($this->hash, 2, 1) - . "/{$this->hash}.png" ); - $alt = trim(str_replace("\n", ' ', htmlspecialchars( $this->tex ))); - return "\"$alt\""; + $url = $this->_mathImageUrl(); + + return Xml::element( 'img', + $this->_attribs( + 'img', + array( + 'class' => 'tex', + 'alt' => $this->tex ), + array( + 'src' => $url ) ) ); } + function _mathImageUrl() { + global $wgMathPath; + $dir = $this->_getHashSubPath(); + return "$wgMathPath/$dir/{$this->hash}.png"; + } + function _getHashPath() { global $wgMathDirectory; - $path = $wgMathDirectory .'/'. substr($this->hash, 0, 1) - .'/'. substr($this->hash, 1, 1) - .'/'. substr($this->hash, 2, 1); + $path = $wgMathDirectory .'/' . $this->_getHashSubPath(); wfDebug( "TeX: getHashPath, hash is: $this->hash, path is: $path\n" ); return $path; } + + function _getHashSubPath() { + return substr($this->hash, 0, 1) + .'/'. substr($this->hash, 1, 1) + .'/'. substr($this->hash, 2, 1); + } - public static function renderMath( $tex ) { + public static function renderMath( $tex, $params=array() ) { global $wgUser; - $math = new MathRenderer( $tex ); + $math = new MathRenderer( $tex, $params ); $math->setOutputMode( $wgUser->getOption('math')); return $math->render(); } } -?>