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

Reply via email to