2014-06-05 22:12:33 +00:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* Description of SpecialMathShowSVG
|
|
|
|
*
|
|
|
|
* @author Moritz Schubotz (Physikerwelt)
|
|
|
|
*/
|
|
|
|
class SpecialMathShowImage extends SpecialPage {
|
|
|
|
private $noRender = false;
|
|
|
|
private $renderer = null;
|
2015-07-22 22:10:46 +00:00
|
|
|
private $mode = 'mathml';
|
2014-06-05 22:12:33 +00:00
|
|
|
|
|
|
|
function __construct() {
|
2014-06-28 08:59:55 +00:00
|
|
|
parent::__construct(
|
|
|
|
'MathShowImage',
|
|
|
|
'', // Don't restrict
|
|
|
|
false // Don't show on Special:SpecialPages - it's not useful interactively
|
|
|
|
);
|
2014-06-05 22:12:33 +00:00
|
|
|
}
|
2014-12-09 14:30:55 +00:00
|
|
|
|
2014-06-05 22:12:33 +00:00
|
|
|
/**
|
|
|
|
* Sets headers - this should be called from the execute() method of all derived classes!
|
2014-12-09 14:30:55 +00:00
|
|
|
* @param bool $success
|
2014-06-05 22:12:33 +00:00
|
|
|
*/
|
|
|
|
function setHeaders( $success = true ) {
|
|
|
|
$out = $this->getOutput();
|
|
|
|
$request = $this->getRequest();
|
|
|
|
$out->setArticleBodyOnly( true );
|
|
|
|
$out->setArticleRelated( false );
|
|
|
|
$out->setRobotPolicy( "noindex,nofollow" );
|
|
|
|
$out->disable();
|
2015-07-22 22:10:46 +00:00
|
|
|
if ( $success && $this->mode == 'png' ) {
|
2014-06-05 22:12:33 +00:00
|
|
|
$request->response()->header( "Content-type: image/png;" );
|
|
|
|
} else {
|
|
|
|
$request->response()->header( "Content-type: image/svg+xml; charset=utf-8" );
|
|
|
|
}
|
|
|
|
if ( $success && !( $this->noRender ) ) {
|
2015-09-21 16:14:01 +00:00
|
|
|
$request->response()->header(
|
|
|
|
'Cache-Control: public, s-maxage=604800, max-age=3600'
|
|
|
|
); // 1 week (server) 1 hour (client)
|
2014-06-05 22:12:33 +00:00
|
|
|
$request->response()->header( 'Vary: User-Agent' );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function execute( $par ) {
|
2017-08-16 05:50:44 +00:00
|
|
|
global $wgMathEnableExperimentalInputFormats, $wgMathoidCli;
|
2014-06-05 22:12:33 +00:00
|
|
|
$request = $this->getRequest();
|
|
|
|
$hash = $request->getText( 'hash', '' );
|
2014-08-25 21:34:25 +00:00
|
|
|
$tex = $request->getText( 'tex', '' );
|
|
|
|
if ( $wgMathEnableExperimentalInputFormats ) {
|
|
|
|
$asciimath = $request->getText( 'asciimath', '' );
|
|
|
|
} else {
|
|
|
|
$asciimath = '';
|
|
|
|
}
|
2017-08-16 05:50:44 +00:00
|
|
|
$mode = $request->getText( 'mode' );
|
|
|
|
$this->mode = MathHooks::mathModeToString( $mode, 'mathml' );
|
|
|
|
|
2015-07-22 22:10:46 +00:00
|
|
|
if ( !in_array( $this->mode, MathRenderer::getValidModes() ) ) {
|
2014-08-25 21:34:25 +00:00
|
|
|
// Fallback to the default if an invalid mode was specified
|
2015-07-22 22:10:46 +00:00
|
|
|
$this->mode = 'mathml';
|
2014-08-25 21:34:25 +00:00
|
|
|
}
|
2014-06-05 22:12:33 +00:00
|
|
|
if ( $hash === '' && $tex === '' && $asciimath === '' ) {
|
|
|
|
$this->setHeaders( false );
|
|
|
|
echo $this->printSvgError( 'No Inputhash specified' );
|
|
|
|
} else {
|
2017-06-20 07:11:57 +00:00
|
|
|
if ( $tex === '' && $asciimath === '' ) {
|
2017-08-16 05:50:44 +00:00
|
|
|
if ( $wgMathoidCli && $this->mode === 'png' ) {
|
|
|
|
$this->renderer = MathRenderer::getRenderer( '', [], 'mathml' );
|
|
|
|
} else {
|
|
|
|
$this->renderer = MathRenderer::getRenderer( '', [], $this->mode );
|
2014-06-05 22:12:33 +00:00
|
|
|
}
|
2017-08-16 05:50:44 +00:00
|
|
|
$this->renderer->setMd5( $hash );
|
2014-06-05 22:12:33 +00:00
|
|
|
$this->noRender = $request->getBool( 'noRender', false );
|
2014-07-25 20:09:34 +00:00
|
|
|
$isInDatabase = $this->renderer->readFromDatabase();
|
|
|
|
if ( $isInDatabase || $this->noRender ) {
|
|
|
|
$success = $isInDatabase;
|
2014-06-05 22:12:33 +00:00
|
|
|
} else {
|
2017-08-16 05:50:44 +00:00
|
|
|
if ( $this->mode == 'png' && !$wgMathoidCli ) {
|
2014-07-25 20:09:34 +00:00
|
|
|
// get the texvc input from the mathoid database table
|
|
|
|
// and render the conventional way
|
2014-06-05 22:12:33 +00:00
|
|
|
$mmlRenderer = MathMathML::newFromMd5( $hash );
|
|
|
|
$mmlRenderer->readFromDatabase();
|
2015-09-21 16:14:01 +00:00
|
|
|
$this->renderer = MathRenderer::getRenderer(
|
2016-04-12 20:53:25 +00:00
|
|
|
$mmlRenderer->getUserInputTex(), [], 'png'
|
2015-09-21 16:14:01 +00:00
|
|
|
);
|
2014-07-25 20:09:34 +00:00
|
|
|
$this->renderer->setMathStyle( $mmlRenderer->getMathStyle() );
|
2014-06-05 22:12:33 +00:00
|
|
|
}
|
|
|
|
$success = $this->renderer->render();
|
|
|
|
}
|
|
|
|
} elseif ( $asciimath === '' ) {
|
2016-04-12 20:53:25 +00:00
|
|
|
$this->renderer = MathRenderer::getRenderer( $tex, [], $this->mode );
|
2014-06-05 22:12:33 +00:00
|
|
|
$success = $this->renderer->render();
|
|
|
|
} else {
|
2015-09-21 16:14:01 +00:00
|
|
|
$this->renderer = MathRenderer::getRenderer(
|
2016-04-12 20:53:25 +00:00
|
|
|
$asciimath, [ 'type' => 'ascii' ], $this->mode
|
2015-09-21 16:14:01 +00:00
|
|
|
);
|
2014-06-05 22:12:33 +00:00
|
|
|
$success = $this->renderer->render();
|
|
|
|
}
|
|
|
|
if ( $success ) {
|
2015-07-22 22:10:46 +00:00
|
|
|
if ( $this->mode == 'png' ) {
|
2014-06-05 22:12:33 +00:00
|
|
|
$output = $this->renderer->getPng();
|
|
|
|
} else {
|
|
|
|
$output = $this->renderer->getSvg();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Error message in PNG not supported
|
|
|
|
$output = $this->printSvgError( $this->renderer->getLastError() );
|
|
|
|
}
|
|
|
|
if ( $output == "" ) {
|
|
|
|
$output = $this->printSvgError( 'No Output produced' );
|
|
|
|
$success = false;
|
|
|
|
}
|
|
|
|
$this->setHeaders( $success );
|
|
|
|
echo $output;
|
2017-06-20 07:11:57 +00:00
|
|
|
if ( $success ) {
|
2014-07-25 20:09:34 +00:00
|
|
|
$this->renderer->writeCache();
|
|
|
|
}
|
2014-06-05 22:12:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Prints the specified error message as svg.
|
|
|
|
* @param string $msg error message
|
2015-08-09 10:45:57 +00:00
|
|
|
* @return string xml svg image with the error message
|
2014-06-05 22:12:33 +00:00
|
|
|
*/
|
|
|
|
private function printSvgError( $msg ) {
|
2015-07-12 19:40:34 +00:00
|
|
|
global $wgDebugComments;
|
2015-09-21 16:14:01 +00:00
|
|
|
// @codingStandardsIgnoreStart
|
|
|
|
$result = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 4" preserveAspectRatio="xMidYMid meet" >' .
|
2014-06-05 22:12:33 +00:00
|
|
|
'<text text-anchor="start" fill="red" y="2">' . htmlspecialchars( $msg ) . '</text></svg>';
|
2015-09-21 16:14:01 +00:00
|
|
|
// @codingStandardsIgnoreEnd
|
2015-07-12 19:40:34 +00:00
|
|
|
if ( $wgDebugComments ) {
|
2015-09-21 16:14:01 +00:00
|
|
|
$result .= '<!--'. var_export( $this->renderer, true ) .'-->';
|
2014-06-05 22:12:33 +00:00
|
|
|
}
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2015-05-16 10:37:42 +00:00
|
|
|
protected function getGroupName() {
|
|
|
|
return 'other';
|
|
|
|
}
|
2014-06-28 08:59:55 +00:00
|
|
|
}
|