Physikerwelt has uploaded a new change for review.
https://gerrit.wikimedia.org/r/113762
Change subject: WIP: Generate SVG from LaTeXML output
......................................................................
WIP: Generate SVG from LaTeXML output
Change-Id: Ie9d03bcdda42e937c643df01bd0316dd82d33aae
---
M Math.hooks.php
M MathLaTeXML.php
M MathMathML.php
M MathRenderer.php
D MathSvg.php
M SpecialMathShowImage.php
D db/debug_fields_math.sql
D db/drop_math_html.sql
D db/drop_math_outputhash.sql
D db/field_math_inputtex.sql
D db/field_math_png.sql
D db/field_math_svg.sql
D db/field_math_tex.sql
A db/math_latexml.mysql.sql
14 files changed, 146 insertions(+), 165 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Math
refs/changes/62/113762/1
diff --git a/Math.hooks.php b/Math.hooks.php
index fec8525..e7a0fdf 100644
--- a/Math.hooks.php
+++ b/Math.hooks.php
@@ -155,7 +155,7 @@
* @return bool
*/
static function onLoadExtensionSchemaUpdates( $updater = null ) {
- global $wgMathDebug;
+ global $wgMathDebug, $wgMathValidModes;
if ( is_null( $updater ) ) {
throw new MWException( "Math extension is only
necessary in 1.18 or above" );
}
@@ -172,6 +172,15 @@
} else {
throw new MWException( "Math extension does not
currently support $type database.\n" );
}
+ if ( in_array( MW_MATH_LATEXML, $wgMathValidModes ) ){
+ if ( $type == 'mysql' ) {
+ //keep $type rather than mysql here for forward
compatibility
+ $sql = dirname( __FILE__ ) .
'/db/math_latexml.' . $type . '.sql';
+ $updater->addExtensionTable( 'math_latexml',
$sql );
+ } else {
+ throw new MWException( "Math extension does not
currently support $type database for LaTeXML." );
+ }
+ }
if ( $wgMathDebug ) {
if ( $type == 'mysql' ) {
$dir = dirname( __FILE__ ) .
'/db/debug_fields_';
diff --git a/MathLaTeXML.php b/MathLaTeXML.php
index 6bab530..01c1a78 100644
--- a/MathLaTeXML.php
+++ b/MathLaTeXML.php
@@ -10,13 +10,17 @@
* @file
*/
class MathLaTeXML extends MathMathML {
-
- /**
- * @var String settings for LaTeXML daemon
- */
+ protected static $DEFAULT_ALLOWED_ROOT_ELEMENTS = array( 'math', 'div',
'table', 'query' );
+ /** @var String settings for LaTeXML daemon */
private $LaTeXMLSettings = '';
/** @var boolean if false LaTeXML output is not validated*/
private $XMLValidation = true;
+
+ public function __construct( $tex = '', $params = array() ) {
+ global $wgMathLaTeXMLUrl;
+ parent::__construct( $tex, $params );
+ $this->hosts = $wgMathLaTeXMLUrl;
+ }
/**
* Converts an array with LaTeXML settings to a URL encoded String.
* If the argument is a string the input will be returned.
@@ -65,50 +69,11 @@
}
/**
- * Gets the allowed root elements the rendered math tag might have.
- *
- * @return array
- */
- public function getAllowedRootElements() {
- if ( $this->allowedRootElements ) {
- return $this->allowedRootElements;
- } else {
- return self::$DEFAULT_ALLOWED_ROOT_ELEMENTS;
- }
- }
-
- /**
- * Sets the allowed root elements the rendered math tag might have.
- * An empty value indicates to use the default settings.
- * @param array $settings
- */
- public function setAllowedRootElments( $settings ) {
- $this->allowedRootElements = $settings;
- }
-
- /**
- * Picks a LaTeXML daemon.
- * If more than one demon are availible one is chosen from the
- * $wgLaTeXMLUrl array.
- * @return string
- */
- private static function pickHost() {
- global $wgMathLaTeXMLUrl;
- if ( is_array( $wgMathLaTeXMLUrl ) ) {
- $host = array_rand( $wgMathLaTeXMLUrl );
- } else {
- $host = $wgMathLaTeXMLUrl;
- }
- wfDebugLog( "Math", "picking host " . $host );
- return $host;
- }
-
- /**
* Calculates the HTTP POST Data for the request. Depends on the
settings
* and the input string only.
* @return string HTTP POST data
*/
- public function getPostData() {
+ public function getLaTeXMLPostData() {
$tex = $this->getTex();
if ( is_null( $this->getDisplayStyle() ) ) {
// default preserve the (broken) layout as it was
@@ -116,7 +81,7 @@
}
$texcmd = rawurlencode( $tex );
$settings = $this->serializeSettings(
$this->getLaTeXMLSettings() );
- $postData = $settings . '&tex=' . $texcmd;
+ $postData = $settings . '&tex=literal:' . $texcmd;
wfDebugLog( "Math", 'Get post data: ' . $postData );
return $postData;
}
@@ -134,8 +99,8 @@
return false;
}
$res = '';
- $host = self::pickHost();
- $post = $this->getPostData();
+ $host = $this->pickHost();
+ $post = $this->getLaTeXMLPostData();
$this->lastError = '';
$requestResult = $this->makeRequest( $host, $post, $res,
$this->lastError );
if ( $requestResult ) {
@@ -178,4 +143,34 @@
$this->XMLValidation = $newval;
}
+ /**
+ * Caclualates the SVG image based on the MathML input
+ * No cache is used.
+ * @return boolean
+ */
+ public function calulateSvg(){
+ $renderer = new MathMathML( $this->getTex() );
+ $renderer->setMathml( $this->getMathml() );
+ $renderer->setMode( MW_MATH_LATEXML );
+ $renderer->setPurge( true );
+ $res = $renderer->render();
+ if ( $res == true ){
+ $this->svg = $renderer->getSvg();
+ } else{
+ $lastError = $renderer->getLastError();
+ wfDebugLog('Math','failed to convert LaTeXML-MathML to
SVG:' . $lastError);
+ }
+
+ return $res;
+ }
+ /**
+ * gets the svg image... supports lazy evaluation
+ * @return string XML-Document of the rendered SVG
+ */
+ public function getSvg(){
+ if( $this->isPurge() || $this->svg == '' ){
+ $this->calulateSvg();
+ }
+ return $this->svg;
+ }
}
\ No newline at end of file
diff --git a/MathMathML.php b/MathMathML.php
index bc916de..04fe180 100644
--- a/MathMathML.php
+++ b/MathMathML.php
@@ -11,8 +11,15 @@
*/
class MathMathML extends MathRenderer {
- protected static $DEFAULT_ALLOWED_ROOT_ELEMENTS = array( 'math', 'div',
'table', 'query' );
+ protected static $DEFAULT_ALLOWED_ROOT_ELEMENTS = array( 'math' );
protected $allowedRootElements = '';
+ protected $hosts;
+
+ public function __construct( $tex = '', $params = array() ) {
+ global $wgMathMathMLUrl;
+ parent::__construct( $tex, $params );
+ $this->hosts = $wgMathMathMLUrl;
+ }
/**
* Gets the allowed root elements the rendered math tag might have.
@@ -140,12 +147,11 @@
* $wgMathMathMLUrl array.
* @return string
*/
- private static function pickHost() {
- global $wgMathMathMLUrl;
- if ( is_array( $wgMathMathMLUrl ) ) {
- $host = array_rand( $wgMathMathMLUrl );
+ protected function pickHost() {
+ if ( is_array( $this->hosts ) ) {
+ $host = array_rand( $this->hosts );
} else {
- $host = $wgMathMathMLUrl;
+ $host = $this->hosts;
}
wfDebugLog( "Math", "picking host " . $host );
return $host;
@@ -157,13 +163,18 @@
* @return string HTTP POST data
*/
public function getPostData() {
+ global $wgMathValidModes;
$tex = $this->getTex();
if ( is_null( $this->getDisplaystyle() ) ) {
// default preserve the (broken) layout as it was
$tex = '{\\displaystyle ' . $tex . '}';
}
+ $out = 'tex=' . rawurlencode( $tex );
+ if ( $this->getMode() == MW_MATH_LATEXML && $this->getMathml()
){
+ $out .= '&mml='.rawurlencode( $this->getMathml() );
+ }
wfDebugLog( "Math", 'Get post data: ' . $tex );
- return 'tex=' . rawurlencode( $tex );
+ return $out;
}
/**
@@ -171,7 +182,7 @@
* @return boolean
*/
protected function doRender() {
- global $wgMathDebug;
+ global $wgMathDebug, $wgMathValidModes;
if ( $this->getTex() === '' ) {
wfDebugLog( 'Math', 'Rendering was requested, but no
TeX string is specified.' );
$this->lastError = $this->getError( 'math_empty_tex' );
@@ -187,10 +198,12 @@
if ( $result && json_last_error() === JSON_ERROR_NONE )
{
if ( $result->sucess ) {
if ( $this->isValidMathML( $result->mml
) ) {
- $this->setMathml( $result->mml
);
$this->setSvg( $result->svg );
if ( $wgMathDebug ) {
$this->setLog(
$result->log );
+ }
+ if ( $this->getMode() !=
MW_MATH_LATEXML ) {
+ $this->setMathml(
$result->mml );
}
return true;
} else {
@@ -252,24 +265,29 @@
* @param boolean $noRender
* @return type
*/
- private function getFallbackImageUrl( $png = false, $noRender = false )
{
+ private function getFallbackImageUrl( $mode = MW_MATH_MATHML, $noRender
= false ) {
return SpecialPage::getTitleFor( 'MathShowImage'
)->getLocalURL( array(
'hash' => $this->getMd5(),
- 'png' => $png,
+ 'mode' => $mode,
'noRender' => $noRender )
);
}
/**
* Gets img tag for math image
- * @param boolean $png if true a png is used instead of an svg image
+ * @param int $mode if true a png is used instead of an svg image
* @param boolean $noRender if true no rendering will be performed if
the image is not stored in the database
- * @param string|false $classOverride if classOverride is false the
class name will be calcuated by getClassName
- * @return string XML the image html tag
+ * @param bool $classOverride
+ * @internal param $ (string|false) $classOverride if classOverride is
false the class name will be calculated by getClassName
+ * @return string XML the image html tag
*/
- public function getFallbackImage( $png = false, $noRender = false,
$classOverride = false ) {
- $url = $this->getFallbackImageUrl( $png , $noRender );
- $style = '';
+ public function getFallbackImage( $mode = MW_MATH_MATHML, $noRender =
false, $classOverride = false ) {
+ $url = $this->getFallbackImageUrl( $mode , $noRender );
+ if ( $mode == MW_MATH_PNG ){
+ $png = true;
+ } else {
+ $png = false;
+ }
$attribs = array();
if ( $classOverride === false ) { // $class ='' suppresses
class attribute
$class = $this->getClassName( true, $png );
@@ -348,9 +366,13 @@
$output .= Xml::tags( $element, array( 'class' =>
$this->getClassName(),
'style' => 'display: none;' ),
$mml );
- $output .= $this->getFallbackImage( false ) . "\n";
- $output .= $this->getFallbackImage( true ) . "\n";
+ $output .= $this->getFallbackImage( $this->getMode() ) . "\n";
+ $output .= $this->getFallbackImage( MW_MATH_PNG ) . "\n";
$output .= HTML::closeElement( $element );
return $output;
}
+
+ protected function getMathTableName() {
+ return 'math_latexml';
+ }
}
\ No newline at end of file
diff --git a/MathRenderer.php b/MathRenderer.php
index c580c25..a8f2656 100644
--- a/MathRenderer.php
+++ b/MathRenderer.php
@@ -438,6 +438,20 @@
}
/**
+ * Sets the rendering mode
+ * @param int $newMode element of the array $wgMathValidModes
+ * @return bool
+ */
+ public function setMode($newMode){
+ global$wgMathValidModes;
+ if (in_array($newMode, $wgMathValidModes )){
+ $this->mode = $newMode;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ /**
* Sets the TeX code
*
* @param string $tex
diff --git a/MathSvg.php b/MathSvg.php
deleted file mode 100644
index e20709c..0000000
--- a/MathSvg.php
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-/**
- * MediaWiki math extension
- *
- * (c) 2002-2012 Tomasz Wegrzanowski, Brion Vibber, Moritz Schubotz and other
MediaWiki contributors
- * GPLv2 license; info in main package.
- *
- * Contains everything related to <math> </math> parsing
- * @file
- */
-
-
-/**
- * Takes LaTeX fragments and outputs the source directly to the browser
- *
- * @author Tomasz Wegrzanowski
- * @author Brion Vibber
- * @author Moritz Schubotz
- * @ingroup Parser
- */
-class MathSvg extends MathRenderer {
- private $svg = '';
- /**
- * Renders TeX by outputting it to the browser in a span tag
- *
- * @return string span tag with TeX
- */
- function getHtmlOutput() {
- # No need to render or parse anything more!
- # New lines are replaced with spaces, which avoids confusing
our parser (bugs 23190, 22818)
- return Xml::element( 'span',
- $this->getAttributes(
- 'span',
- array(
- 'class' => 'tex',
- 'dir' => 'ltr'
- )
- ),
- '$ ' . str_replace( "\n", " ", $this->getTex() ) . ' $'
- );
- }
- /**
- * No rendering required in plain text mode
- * @return boolean
- */
- function render() {
- global $wgMathLaTeXMLTimeout;
- $post = $this->getTex();
- $host = 'http://localhost:16000/';
- $options = array( 'method' => 'POST', 'postData' => $post,
'timeout' => $wgMathLaTeXMLTimeout );
- $req = MWHttpRequest::factory( $host, $options );
- $status = $req->execute();
- if ( $status->isGood() ) {
- $this->svg = $req->getContent();
- return true;
- } else {
- return false;
- }
- }
- public function getSvg() {
- return $this->svg;
- }
-}
diff --git a/SpecialMathShowImage.php b/SpecialMathShowImage.php
index 214e643..0700af2 100644
--- a/SpecialMathShowImage.php
+++ b/SpecialMathShowImage.php
@@ -13,7 +13,7 @@
class SpecialMathShowImage extends SpecialPage {
private $noRender = false;
private $renderer = null;
- private $isPng = false;
+ private $mode = false;
function __construct() {
parent::__construct( 'MathShowImage' );
@@ -28,7 +28,7 @@
$out->setArticleRelated( false );
$out->setRobotPolicy( "noindex,nofollow" );
$out->disable();
- if ( $success && $this->isPng ) {
+ if ( $success && $this->mode == MW_MATH_PNG ) {
$request->response()->header( "Content-type:
image/png;" );
} else {
$request->response()->header( "Content-type:
image/svg+xml; charset=utf-8" );
@@ -43,14 +43,19 @@
$request = $this->getRequest();
$output = '';
$hash = $request->getText( 'hash', '' );
- $this->isPng = $request->getBool( 'png', false );
+ $this->mode = $request->getBool( 'png', MW_MATH_MATHML );
if ( !$hash ) {
$this->setHeaders( false );
$output = $this->printSvgError( 'No Inputhash
specified' );
} else {
- if ( $this->isPng ) {
+ switch ( $this->mode ){
+ case MW_MATH_PNG:
$this->renderer = MathTexvc::newFromMd5( $hash
);
- } else {
+ break;
+ case MW_MATH_LATEXML:
+ $this->renderer = MathLaTeXML::newFromMd5(
$hash );
+ break;
+ default:
$this->renderer = MathMathML::newFromMd5( $hash
);
}
$this->noRender = $request->getBool( 'noRender', false
);
@@ -60,7 +65,7 @@
$success = $this->renderer->render();
}
if ( $success ) {
- if ( $this->isPng ) {
+ if ( $this->mode == MW_MATH_PNG ) {
$output = $this->renderer->getPng();
} else {
$output = $this->renderer->getSvg();
diff --git a/db/debug_fields_math.sql b/db/debug_fields_math.sql
deleted file mode 100644
index 7e98928..0000000
--- a/db/debug_fields_math.sql
+++ /dev/null
@@ -1,11 +0,0 @@
---
--- Used by the math module to keep extra information for debugging
---
-ALTER TABLE /*_*/math ADD math_tex text;
-ALTER TABLE /*_*/math Add math_status int(4);
-ALTER TABLE /*_*/math ADD valid_xml tinyint(1);
-ALTER TABLE /*_*/math ADD math_log text;
-ALTER TABLE /*_*/math ADD math_timestamp timestamp NULL DEFAULT
CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
-ALTER TABLE /*_*/math ADD KEY `math_timestamp` (`math_timestamp`);
-ALTER TABLE /*_*/math ADD KEY `math_status` (`math_status`);
-ALTER TABLE /*_*/math ADD KEY `valid_xml` (`valid_xml`);
\ No newline at end of file
diff --git a/db/drop_math_html.sql b/db/drop_math_html.sql
deleted file mode 100644
index 96e17a7..0000000
--- a/db/drop_math_html.sql
+++ /dev/null
@@ -1 +0,0 @@
-ALTER TABLE /*_*/math DROP math_html;
\ No newline at end of file
diff --git a/db/drop_math_outputhash.sql b/db/drop_math_outputhash.sql
deleted file mode 100644
index f99a06a..0000000
--- a/db/drop_math_outputhash.sql
+++ /dev/null
@@ -1 +0,0 @@
-ALTER TABLE /*_*/math DROP math_outputhash;
\ No newline at end of file
diff --git a/db/field_math_inputtex.sql b/db/field_math_inputtex.sql
deleted file mode 100644
index 8db4111..0000000
--- a/db/field_math_inputtex.sql
+++ /dev/null
@@ -1,4 +0,0 @@
---
--- Used by the math module to keep extra information for debugging and texvc
---
-ALTER TABLE /*_*/math ADD math_inputtex text;
\ No newline at end of file
diff --git a/db/field_math_png.sql b/db/field_math_png.sql
deleted file mode 100644
index 86f5351..0000000
--- a/db/field_math_png.sql
+++ /dev/null
@@ -1,4 +0,0 @@
---
--- Used by the math module to keep extra information for debugging
---
-ALTER TABLE /*_*/math ADD math_png blob;
\ No newline at end of file
diff --git a/db/field_math_svg.sql b/db/field_math_svg.sql
deleted file mode 100644
index bdc66e5..0000000
--- a/db/field_math_svg.sql
+++ /dev/null
@@ -1,4 +0,0 @@
---
--- Used by the math module to keep extra information for debugging
---
-ALTER TABLE /*_*/math ADD math_svg text;
\ No newline at end of file
diff --git a/db/field_math_tex.sql b/db/field_math_tex.sql
deleted file mode 100644
index 2371d38..0000000
--- a/db/field_math_tex.sql
+++ /dev/null
@@ -1,4 +0,0 @@
---
--- Used by the math module to render delayed in a seperate process
---
-ALTER TABLE /*_*/math ADD math_tex text;
\ No newline at end of file
diff --git a/db/math_latexml.mysql.sql b/db/math_latexml.mysql.sql
new file mode 100644
index 0000000..931c84c
--- /dev/null
+++ b/db/math_latexml.mysql.sql
@@ -0,0 +1,28 @@
+--
+-- Used by the math module to keep track
+-- of previously-rendered items.
+--
+CREATE TABLE /*_*/math_latexml (
+ -- Binary MD5 hash of math_inputtex, used as an identifier key.
+ math_inputhash varbinary(16) NOT NULL PRIMARY KEY,
+ -- the user input
+ math_inputtex text NOT NULL,
+ -- the validated tex
+ math_tex text,
+ -- MathML output LaTeXML
+ math_mathml text,
+ -- SVG output mathoid
+ math_svg text,
+ -- return status of LaTeXML
+ math_status int(4),
+ -- flag if MathML is valid XML
+ valid_xml tinyint(1),
+ -- LOG output of LaTeXML
+ math_log text,
+ -- Timestamp of the last update
+ math_timestamp timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP,
+ -- Indexes to find broken math
+ KEY math_timestamp (math_timestamp),
+ KEY math_status (math_status),
+ KEY valid_xml (valid_xml)
+) /*$wgDBTableOptions*/;
--
To view, visit https://gerrit.wikimedia.org/r/113762
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie9d03bcdda42e937c643df01bd0316dd82d33aae
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Math
Gerrit-Branch: dev
Gerrit-Owner: Physikerwelt <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits