mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Math
synced 2024-11-23 23:25:02 +00:00
Math extension:
*coding style tweaks *documentation *check for MediaWiki environment in the main setup file *add extension credits *add i18n file (only English at the moment); messages from core MessagesEn.php This is a follow-up to Brion's r85706.
This commit is contained in:
parent
d690d96e24
commit
e0b832c637
125
Math.body.php
125
Math.body.php
|
@ -5,7 +5,7 @@
|
|||
* (c) 2002-2011 Tomasz Wegrzanowski, Brion Vibber, and other MediaWiki contributors
|
||||
* GPLv2 license; info in main package.
|
||||
*
|
||||
* Contain everything related to <math> </math> parsing
|
||||
* Contains everything related to <math> </math> parsing
|
||||
* @file
|
||||
* @ingroup Parser
|
||||
*/
|
||||
|
@ -27,7 +27,7 @@ class MathRenderer {
|
|||
var $mathml = '';
|
||||
var $conservativeness = 0;
|
||||
|
||||
function __construct( $tex, $params=array() ) {
|
||||
function __construct( $tex, $params = array() ) {
|
||||
$this->tex = $tex;
|
||||
$this->params = $params;
|
||||
}
|
||||
|
@ -80,46 +80,46 @@ class MathRenderer {
|
|||
$contents = wfShellExec( $cmd );
|
||||
wfDebug( "TeX output:\n $contents\n---\n" );
|
||||
|
||||
if (strlen($contents) == 0) {
|
||||
if ( strlen( $contents ) == 0 ) {
|
||||
return $this->_error( 'math_unknown_error' );
|
||||
}
|
||||
|
||||
$retval = substr ($contents, 0, 1);
|
||||
$retval = substr( $contents, 0, 1 );
|
||||
$errmsg = '';
|
||||
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') {
|
||||
} elseif ( $retval == 'M' ) {
|
||||
$this->conservativeness = 1;
|
||||
} else {
|
||||
$this->conservativeness = 0;
|
||||
}
|
||||
$outdata = substr ($contents, 33);
|
||||
$outdata = substr( $contents, 33 );
|
||||
|
||||
$i = strpos($outdata, "\000");
|
||||
$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->html = substr( $outdata, 0, $i );
|
||||
$this->mathml = substr( $outdata, $i + 1 );
|
||||
} elseif ( ( $retval == 'c' ) || ( $retval == 'm' ) || ( $retval == 'l' ) ) {
|
||||
$this->html = substr( $contents, 33 );
|
||||
if ( $retval == 'c' ) {
|
||||
$this->conservativeness = 2;
|
||||
} else if ($retval == 'm') {
|
||||
} elseif ( $retval == 'm' ) {
|
||||
$this->conservativeness = 1;
|
||||
} else {
|
||||
$this->conservativeness = 0;
|
||||
}
|
||||
$this->mathml = null;
|
||||
} else if ($retval == 'X') {
|
||||
} elseif ( $retval == 'X' ) {
|
||||
$this->html = null;
|
||||
$this->mathml = substr ($contents, 33);
|
||||
$this->mathml = substr( $contents, 33 );
|
||||
$this->conservativeness = 0;
|
||||
} else if ($retval == '+') {
|
||||
} elseif ( $retval == '+' ) {
|
||||
$this->html = null;
|
||||
$this->mathml = null;
|
||||
$this->conservativeness = 0;
|
||||
} else {
|
||||
$errbit = htmlspecialchars( substr($contents, 1) );
|
||||
$errbit = htmlspecialchars( substr( $contents, 1 ) );
|
||||
switch( $retval ) {
|
||||
case 'E':
|
||||
$errmsg = $this->_error( 'math_lexing_error', $errbit );
|
||||
|
@ -136,16 +136,16 @@ class MathRenderer {
|
|||
}
|
||||
|
||||
if ( !$errmsg ) {
|
||||
$this->hash = substr ($contents, 1, 32);
|
||||
$this->hash = substr( $contents, 1, 32 );
|
||||
}
|
||||
|
||||
wfRunHooks( 'MathAfterTexvc', array( &$this, &$errmsg ) );
|
||||
|
||||
if ( $errmsg ) {
|
||||
return $errmsg;
|
||||
return $errmsg;
|
||||
}
|
||||
|
||||
if (!preg_match("/^[a-f0-9]{32}$/", $this->hash)) {
|
||||
if ( !preg_match( "/^[a-f0-9]{32}$/", $this->hash ) ) {
|
||||
return $this->_error( 'math_unknown_error' );
|
||||
}
|
||||
|
||||
|
@ -175,19 +175,22 @@ class MathRenderer {
|
|||
|
||||
# Now save it back to the DB:
|
||||
if ( !wfReadOnly() ) {
|
||||
$outmd5_sql = pack('H32', $this->hash);
|
||||
$outmd5_sql = pack( 'H32', $this->hash );
|
||||
|
||||
$md5_sql = pack('H32', $this->md5); # Binary packed, not hex
|
||||
$md5_sql = pack( 'H32', $this->md5 ); # Binary packed, not hex
|
||||
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$dbw->replace( 'math', array( 'math_inputhash' ),
|
||||
array(
|
||||
'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,
|
||||
), __METHOD__
|
||||
$dbw->replace(
|
||||
'math',
|
||||
array( 'math_inputhash' ),
|
||||
array(
|
||||
'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,
|
||||
),
|
||||
__METHOD__
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -204,7 +207,7 @@ class MathRenderer {
|
|||
}
|
||||
|
||||
function _error( $msg, $append = '' ) {
|
||||
$mf = htmlspecialchars( wfMsg( 'math_failure' ) );
|
||||
$mf = htmlspecialchars( wfMsg( 'math_failure' ) );
|
||||
$errmsg = htmlspecialchars( wfMsg( $msg ) );
|
||||
$source = htmlspecialchars( str_replace( "\n", ' ', $this->tex ) );
|
||||
return "<strong class='error'>$mf ($errmsg$append): $source</strong>\n";
|
||||
|
@ -215,16 +218,22 @@ class MathRenderer {
|
|||
|
||||
$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' => $dbr->encodeBlob(pack("H32", $this->md5))), # Binary packed, not hex
|
||||
$rpage = $dbr->selectRow(
|
||||
'math',
|
||||
array(
|
||||
'math_outputhash', 'math_html_conservativeness', 'math_html',
|
||||
'math_mathml'
|
||||
),
|
||||
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', $dbr->decodeBlob($rpage->math_outputhash) . " " );
|
||||
$this->hash = $xhash ['md5'];
|
||||
$xhash = unpack( 'H32md5', $dbr->decodeBlob( $rpage->math_outputhash ) . " " );
|
||||
$this->hash = $xhash['md5'];
|
||||
|
||||
$this->conservativeness = $rpage->math_html_conservativeness;
|
||||
$this->html = $rpage->math_html;
|
||||
|
@ -261,11 +270,11 @@ class MathRenderer {
|
|||
} elseif( !is_dir( $hashpath ) || !is_writable( $hashpath ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( function_exists( "link" ) ) {
|
||||
return link ( $wgMathDirectory . "/{$this->hash}.png",
|
||||
if ( function_exists( 'link' ) ) {
|
||||
return link( $wgMathDirectory . "/{$this->hash}.png",
|
||||
$hashpath . "/{$this->hash}.png" );
|
||||
} else {
|
||||
return rename ( $wgMathDirectory . "/{$this->hash}.png",
|
||||
return rename( $wgMathDirectory . "/{$this->hash}.png",
|
||||
$hashpath . "/{$this->hash}.png" );
|
||||
}
|
||||
}
|
||||
|
@ -286,9 +295,11 @@ class MathRenderer {
|
|||
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))) {
|
||||
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 Xml::tags( 'span',
|
||||
|
@ -296,11 +307,12 @@ class MathRenderer {
|
|||
array( 'class' => 'texhtml',
|
||||
'dir' => 'ltr'
|
||||
) ),
|
||||
$this->html );
|
||||
$this->html
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function _attribs( $tag, $defaults=array(), $overrides=array() ) {
|
||||
function _attribs( $tag, $defaults = array(), $overrides = array() ) {
|
||||
$attribs = Sanitizer::validateTagAttributes( $this->params, $tag );
|
||||
$attribs = Sanitizer::mergeAttributes( $defaults, $attribs );
|
||||
$attribs = Sanitizer::mergeAttributes( $attribs, $overrides );
|
||||
|
@ -315,9 +327,13 @@ class MathRenderer {
|
|||
'img',
|
||||
array(
|
||||
'class' => 'tex',
|
||||
'alt' => $this->tex ),
|
||||
'alt' => $this->tex
|
||||
),
|
||||
array(
|
||||
'src' => $url ) ) );
|
||||
'src' => $url
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function _mathImageUrl() {
|
||||
|
@ -328,21 +344,22 @@ class MathRenderer {
|
|||
|
||||
function _getHashPath() {
|
||||
global $wgMathDirectory;
|
||||
$path = $wgMathDirectory .'/' . $this->_getHashSubPath();
|
||||
$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);
|
||||
return substr( $this->hash, 0, 1)
|
||||
. '/' . substr( $this->hash, 1, 1 )
|
||||
. '/' . substr( $this->hash, 2, 1 );
|
||||
}
|
||||
|
||||
public static function renderMath( $tex, $params=array(), ParserOptions $parserOptions = null ) {
|
||||
public static function renderMath( $tex, $params = array(), ParserOptions $parserOptions = null ) {
|
||||
$math = new MathRenderer( $tex, $params );
|
||||
if ( $parserOptions )
|
||||
if ( $parserOptions ) {
|
||||
$math->setOutputMode( $parserOptions->getMath() );
|
||||
}
|
||||
return $math->render();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,30 +7,55 @@
|
|||
*/
|
||||
|
||||
class MathHooks {
|
||||
/**
|
||||
* Set up $wgMathPath and $wgMathDirectory globals if they're not already
|
||||
* set.
|
||||
*/
|
||||
static function setup() {
|
||||
global $wgMathPath, $wgMathDirectory;
|
||||
global $wgUploadPath, $wgUploadDirectory;
|
||||
if ( $wgMathPath === false ) $wgMathPath = "{$wgUploadPath}/math";
|
||||
if ( $wgMathDirectory === false ) $wgMathDirectory = "{$wgUploadDirectory}/math";
|
||||
if ( $wgMathPath === false ) {
|
||||
$wgMathPath = "{$wgUploadPath}/math";
|
||||
}
|
||||
if ( $wgMathDirectory === false ) {
|
||||
$wgMathDirectory = "{$wgUploadDirectory}/math";
|
||||
}
|
||||
}
|
||||
|
||||
static function onParserFirstCallInit($parser)
|
||||
{
|
||||
/**
|
||||
* Register the <math> tag with the Parser.
|
||||
*
|
||||
* @param $parser Object: instance of Parser
|
||||
* @return Boolean: true
|
||||
*/
|
||||
static function onParserFirstCallInit( $parser ) {
|
||||
$parser->setHook( 'math', array( 'MathHooks', 'mathTagHook' ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $content
|
||||
* @param $attributes
|
||||
* Callback function for the <math> parser hook.
|
||||
*
|
||||
* @param $content
|
||||
* @param $attributes
|
||||
* @param $parser Parser
|
||||
* @return
|
||||
*/
|
||||
static function mathTagHook( $content, $attributes, $parser ) {
|
||||
global $wgContLang;
|
||||
return $wgContLang->armourMath( MathRenderer::renderMath( $content, $attributes, $parser->getOptions() ) );
|
||||
$renderedMath = MathRenderer::renderMath(
|
||||
$content, $attributes, $parser->getOptions()
|
||||
);
|
||||
return $wgContLang->armourMath( $renderedMath );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the new math rendering options to Special:Preferences.
|
||||
*
|
||||
* @param $user Object: current User object
|
||||
* @param $defaultPreferences Object: Preferences object
|
||||
* @return Boolean: true
|
||||
*/
|
||||
static function onGetPreferences( $user, &$defaultPreferences ) {
|
||||
global $wgLang;
|
||||
$defaultPreferences['math'] = array(
|
||||
|
|
38
Math.i18n.php
Normal file
38
Math.i18n.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
/**
|
||||
* Internationalization file for the Math extension.
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
|
||||
$messages = array();
|
||||
|
||||
/** English */
|
||||
$messages['en'] = array(
|
||||
// Edit toolbar stuff shown on ?action=edit (example text & tooltip)
|
||||
'math_sample' => 'Insert formula here',
|
||||
'math_tip' => 'Mathematical formula (LaTeX)',
|
||||
|
||||
// Header on Special:Preferences (or something)
|
||||
'prefs-math' => 'Math',
|
||||
|
||||
// Math options
|
||||
'mw_math_png' => 'Always render PNG',
|
||||
'mw_math_simple' => 'HTML if very simple or else PNG',
|
||||
'mw_math_html' => 'HTML if possible or else PNG',
|
||||
'mw_math_source' => 'Leave it as TeX (for text browsers)',
|
||||
'mw_math_modern' => 'Recommended for modern browsers',
|
||||
'mw_math_mathml' => 'MathML if possible (experimental)',
|
||||
|
||||
// Math errors
|
||||
'math_failure' => 'Failed to parse',
|
||||
'math_unknown_error' => 'unknown error',
|
||||
'math_unknown_function' => 'unknown function',
|
||||
'math_lexing_error' => 'lexing error',
|
||||
'math_syntax_error' => 'syntax error',
|
||||
'math_image_error' => 'PNG conversion failed; check for correct installation of latex and dvipng (or dvips + gs + convert)',
|
||||
'math_bad_tmpdir' => 'Cannot write to or create math temp directory',
|
||||
'math_bad_output' => 'Cannot write to or create math output directory',
|
||||
'math_notexvc' => 'Missing texvc executable; please see math/README to configure.',
|
||||
);
|
48
Math.php
48
Math.php
|
@ -2,21 +2,41 @@
|
|||
/**
|
||||
* MediaWiki math extension
|
||||
*
|
||||
* (c) 2002-2011 various MediaWiki contributors
|
||||
* GPLv2 license; info in main package.
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
* @version 1.0
|
||||
* @author Tomasz Wegrzanowski
|
||||
* @author Brion Vibber
|
||||
* @copyright © 2002-2011 various MediaWiki contributors
|
||||
* @license GPLv2 license; info in main package.
|
||||
* @link http://www.mediawiki.org/wiki/Extension:Math Documentation
|
||||
* @see https://bugzilla.wikimedia.org/show_bug.cgi?id=14202
|
||||
*/
|
||||
|
||||
if ( !defined( 'MEDIAWIKI' ) ) {
|
||||
die( "This is not a valid entry point to MediaWiki.\n" );
|
||||
}
|
||||
|
||||
// Extension credits that will show up on Special:Version
|
||||
$wgExtensionCredits['parserhook'][] = array(
|
||||
'name' => 'Math',
|
||||
'version' => '1.0',
|
||||
'author' => array( 'Tomasz Wegrzanowski', 'Brion Vibber', '...' ),
|
||||
'description' => 'Render mathematical formulas between <code><math></code> ... <code></math></code> tags',
|
||||
'url' => 'http://www.mediawiki.org/wiki/Extension:Math',
|
||||
);
|
||||
|
||||
/** For back-compat */
|
||||
$wgUseTeX = true;
|
||||
|
||||
/** Location of the texvc binary */
|
||||
$wgTexvc = dirname( __FILE__ ) . '/math/texvc';
|
||||
/**
|
||||
* Texvc background color
|
||||
* use LaTeX color format as used in \special function
|
||||
* for transparent background use value 'Transparent' for alpha transparency or
|
||||
* 'transparent' for binary transparency.
|
||||
*/
|
||||
* Texvc background color
|
||||
* use LaTeX color format as used in \special function
|
||||
* for transparent background use value 'Transparent' for alpha transparency or
|
||||
* 'transparent' for binary transparency.
|
||||
*/
|
||||
$wgTexvcBackgroundColor = 'transparent';
|
||||
|
||||
/**
|
||||
|
@ -32,14 +52,13 @@ $wgTexvcBackgroundColor = 'transparent';
|
|||
*/
|
||||
$wgMathCheckFiles = true;
|
||||
|
||||
|
||||
/**
|
||||
* The URL path of the math directory. Defaults to "{$wgUploadPath}/math".
|
||||
*
|
||||
* See http://www.mediawiki.org/wiki/Manual:Enable_TeX for details about how to
|
||||
* set up mathematical formula display.
|
||||
*/
|
||||
$wgMathPath = false;
|
||||
$wgMathPath = false;
|
||||
|
||||
/**
|
||||
* The filesystem path of the math directory.
|
||||
|
@ -48,7 +67,7 @@ $wgMathPath = false;
|
|||
* See http://www.mediawiki.org/wiki/Manual:Enable_TeX for details about how to
|
||||
* set up mathematical formula display.
|
||||
*/
|
||||
$wgMathDirectory = false;
|
||||
$wgMathDirectory = false;
|
||||
|
||||
|
||||
////////// end of config settings.
|
||||
|
@ -58,7 +77,10 @@ $wgExtensionFunctions[] = 'MathHooks::setup';
|
|||
$wgHooks['ParserFirstCallInit'][] = 'MathHooks::onParserFirstCallInit';
|
||||
$wgHooks['GetPreferences'][] = 'MathHooks::onGetPreferences';
|
||||
|
||||
$wgAutoloadClasses['MathHooks'] = dirname( __FILE__ ) . '/Math.hooks.php';
|
||||
$wgAutoloadClasses['MathRenderer'] = dirname( __FILE__ ) . '/Math.body.php';
|
||||
$dir = dirname( __FILE__ ) . '/';
|
||||
$wgAutoloadClasses['MathHooks'] = $dir . 'Math.hooks.php';
|
||||
$wgAutoloadClasses['MathRenderer'] = $dir . 'Math.body.php';
|
||||
|
||||
$wgParserTestFiles[] = dirname( __FILE__ ) . "/mathParserTests.txt";
|
||||
$wgExtensionMessagesFiles['Math'] = $dir . 'Math.i18n.php';
|
||||
|
||||
$wgParserTestFiles[] = $dir . 'mathParserTests.txt';
|
Loading…
Reference in a new issue