mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Math
synced 2024-11-24 15:44:33 +00:00
d8822169ab
Renders formulae via mathoid without to run mathoid as a service. Mathoid 0.7.1 or later must be installed locally and configured to be accessed directly from the math extension. It has been tested with the config.dev.yaml of version 0.7.1. If mathoid is installed in '/srv/mathoid' the following line might be added to LocalSettings.php $wgMathoidCli = ['/srv/mathoid/cli.js', '-c', '/srv/mathoid/config.dev.yaml']; i.e., make sure to specify the -c parameter with an absolute path. In addition mathoid uses more memory than the the default. With the config.dev.yaml a value of $wgMaxShellMemory = 2097152; has been tested to work well. Change-Id: I0600f056d21927963267cf979d342e313419e9fa
141 lines
4.4 KiB
PHP
141 lines
4.4 KiB
PHP
<?php
|
|
/**
|
|
* Description of SpecialMathShowSVG
|
|
*
|
|
* @author Moritz Schubotz (Physikerwelt)
|
|
*/
|
|
class SpecialMathShowImage extends SpecialPage {
|
|
private $noRender = false;
|
|
private $renderer = null;
|
|
private $mode = 'mathml';
|
|
|
|
function __construct() {
|
|
parent::__construct(
|
|
'MathShowImage',
|
|
'', // Don't restrict
|
|
false // Don't show on Special:SpecialPages - it's not useful interactively
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Sets headers - this should be called from the execute() method of all derived classes!
|
|
* @param bool $success
|
|
*/
|
|
function setHeaders( $success = true ) {
|
|
$out = $this->getOutput();
|
|
$request = $this->getRequest();
|
|
$out->setArticleBodyOnly( true );
|
|
$out->setArticleRelated( false );
|
|
$out->setRobotPolicy( "noindex,nofollow" );
|
|
$out->disable();
|
|
if ( $success && $this->mode == 'png' ) {
|
|
$request->response()->header( "Content-type: image/png;" );
|
|
} else {
|
|
$request->response()->header( "Content-type: image/svg+xml; charset=utf-8" );
|
|
}
|
|
if ( $success && !( $this->noRender ) ) {
|
|
$request->response()->header(
|
|
'Cache-Control: public, s-maxage=604800, max-age=3600'
|
|
); // 1 week (server) 1 hour (client)
|
|
$request->response()->header( 'Vary: User-Agent' );
|
|
}
|
|
}
|
|
|
|
function execute( $par ) {
|
|
global $wgMathEnableExperimentalInputFormats, $wgMathoidCli;
|
|
$request = $this->getRequest();
|
|
$hash = $request->getText( 'hash', '' );
|
|
$tex = $request->getText( 'tex', '' );
|
|
if ( $wgMathEnableExperimentalInputFormats ) {
|
|
$asciimath = $request->getText( 'asciimath', '' );
|
|
} else {
|
|
$asciimath = '';
|
|
}
|
|
$mode = $request->getText( 'mode' );
|
|
$this->mode = MathHooks::mathModeToString( $mode, 'mathml' );
|
|
|
|
if ( !in_array( $this->mode, MathRenderer::getValidModes() ) ) {
|
|
// Fallback to the default if an invalid mode was specified
|
|
$this->mode = 'mathml';
|
|
}
|
|
if ( $hash === '' && $tex === '' && $asciimath === '' ) {
|
|
$this->setHeaders( false );
|
|
echo $this->printSvgError( 'No Inputhash specified' );
|
|
} else {
|
|
if ( $tex === '' && $asciimath === '' ) {
|
|
if ( $wgMathoidCli && $this->mode === 'png' ) {
|
|
$this->renderer = MathRenderer::getRenderer( '', [], 'mathml' );
|
|
} else {
|
|
$this->renderer = MathRenderer::getRenderer( '', [], $this->mode );
|
|
}
|
|
$this->renderer->setMd5( $hash );
|
|
$this->noRender = $request->getBool( 'noRender', false );
|
|
$isInDatabase = $this->renderer->readFromDatabase();
|
|
if ( $isInDatabase || $this->noRender ) {
|
|
$success = $isInDatabase;
|
|
} else {
|
|
if ( $this->mode == 'png' && !$wgMathoidCli ) {
|
|
// get the texvc input from the mathoid database table
|
|
// and render the conventional way
|
|
$mmlRenderer = MathMathML::newFromMd5( $hash );
|
|
$mmlRenderer->readFromDatabase();
|
|
$this->renderer = MathRenderer::getRenderer(
|
|
$mmlRenderer->getUserInputTex(), [], 'png'
|
|
);
|
|
$this->renderer->setMathStyle( $mmlRenderer->getMathStyle() );
|
|
}
|
|
$success = $this->renderer->render();
|
|
}
|
|
} elseif ( $asciimath === '' ) {
|
|
$this->renderer = MathRenderer::getRenderer( $tex, [], $this->mode );
|
|
$success = $this->renderer->render();
|
|
} else {
|
|
$this->renderer = MathRenderer::getRenderer(
|
|
$asciimath, [ 'type' => 'ascii' ], $this->mode
|
|
);
|
|
$success = $this->renderer->render();
|
|
}
|
|
if ( $success ) {
|
|
if ( $this->mode == 'png' ) {
|
|
$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;
|
|
if ( $success ) {
|
|
$this->renderer->writeCache();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Prints the specified error message as svg.
|
|
* @param string $msg error message
|
|
* @return string xml svg image with the error message
|
|
*/
|
|
private function printSvgError( $msg ) {
|
|
global $wgDebugComments;
|
|
// @codingStandardsIgnoreStart
|
|
$result = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 4" preserveAspectRatio="xMidYMid meet" >' .
|
|
'<text text-anchor="start" fill="red" y="2">' . htmlspecialchars( $msg ) . '</text></svg>';
|
|
// @codingStandardsIgnoreEnd
|
|
if ( $wgDebugComments ) {
|
|
$result .= '<!--'. var_export( $this->renderer, true ) .'-->';
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
protected function getGroupName() {
|
|
return 'other';
|
|
}
|
|
}
|