Add getHtmlOutput method

Currently the method render always returns
a html string that can be a string that
represents the correct result or a rendered
error message.
This change adds a mechanism that allows
to fetch the HTML output.
In a followup commit the rendering function
is changed to return a boolean value rather
than the rendering result.
This will simplify the error handling and caching.

Change-Id: I80760493e391911c41eb69d75a93c6a34db8852e
This commit is contained in:
physikerwelt 2014-06-05 21:06:43 +00:00 committed by physikerwelt (Moritz Schubotz)
parent 9a645d96df
commit c390f6479a
8 changed files with 88 additions and 25 deletions

View File

@ -56,7 +56,7 @@ class MathMathML extends MathRenderer {
$this->setPurge( true );
}
if ( $this->renderingRequired() ) {
$res = $this->doRender( );
$res = $this->doRender();
if ( ! $res ) {
wfProfileOut( __METHOD__ );
return $this->getLastError();
@ -208,4 +208,53 @@ class MathMathML extends MathRenderer {
protected function getMathTableName() {
return 'mathoid';
}
/**
* Calculates the default class name for a math element
* @param boolean $fallback
* @param boolean $png
* @return string the class name
*/
protected function getClassName( $fallback = false, $png = false ) {
$class = "mwe-math-";
if ( $fallback ) {
$class .= 'fallback-';
if ( $png ) {
$class .= 'png-';
} else {
$class .= 'svg-';
}
} else {
$class .= 'mathml-';
}
if ( $this->getMathStyle() == MW_MATHSTYLE_DISPLAY ) {
$class .= 'display';
} else {
$class .= 'inline';
}
return $class;
}
/**
* @return string Html output that is embedded in the page
*/
public function getHtmlOutput() {
if ( $this->getMathStyle() == MW_MATHSTYLE_DISPLAY ) {
$element = 'div';
} else {
$element = 'span';
}
$attribs = array();
$output = HTML::openElement( $element, $attribs );
// MathML has to be wrapped into a div or span in order to be able to hide it.
if ( $this->getMathStyle() == MW_MATHSTYLE_DISPLAY ) {
// Remove displayStyle attributes set by the MathML converter
$mml = preg_replace( '/(<math[^>]*)(display|mode)=["\'](inline|block)["\']/', '$1', $this->getMathml() );
// and insert the correct value
$mml = preg_replace( '/<math/', '<math display="block"', $mml );
} else {
$mml = $this->getMathml();
}
$output .= Xml::tags( $element, array( 'class' => $this->getClassName(), 'style' => 'display: none;' ), $mml );
$output .= HTML::closeElement( $element );
return $output;
}
}

View File

@ -149,6 +149,10 @@ abstract class MathRenderer {
*/
abstract public function render();
/**
* @return string Html output that is embedded in the page
*/
abstract public function getHtmlOutput();
/**
* texvc error messages

View File

@ -24,7 +24,7 @@ class MathSource extends MathRenderer {
*
* @return string span tag with TeX
*/
function render() {
function getHtmlOutput() {
# No need to render or parse anything more!
# New lines are replaced with spaces, which avoids confusing our parser (bugs 23190, 22818)
if ( $this->getMathStyle() == MW_MATHSTYLE_DISPLAY ) {
@ -49,4 +49,12 @@ class MathSource extends MathRenderer {
protected function getMathTableName() {
throw new MWException ( 'in math source mode no database caching should happen');
}
/**
* No rendering required in plain text mode
* @return boolean
*/
function render() {
return $this->getHtmlOutput();
}
}

View File

@ -86,7 +86,7 @@ class MathTexvc extends MathRenderer {
return $result;
}
}
return $this->doHTMLRender();
return $this->getHtmlOutput();
}
/**
@ -334,7 +334,7 @@ class MathTexvc extends MathRenderer {
*
* @return string HTML string
*/
public function doHTMLRender() {
public function getHtmlOutput() {
if ( $this->getMode() == MW_MATH_MATHML && $this->getMathml() != '' ) {
return Xml::tags( 'math',
$this->getAttributes( 'math',

View File

@ -6,7 +6,15 @@
Shows browser-dependent math output.
*/
.mwe-math-mathml-inline { display: none;}
.mwe-math-mathml-display { display: none ;}
.mwe-math-fallback-png-inline { display: inline; vertical-align: middle}
.mwe-math-fallback-png-display { display: block; margin-left: auto; margin-right: auto;}
.mwe-math-fallback-source-inline { display: inline; vertical-align: middle}
.mwe-math-fallback-source-display { display: block; margin-left: auto; margin-right: auto;}
.mwe-math-fallback-source-display { display: block; margin-left: auto; margin-right: auto;}
@-moz-document url-prefix() {
.mwe-math-mathml-inline { display: inline !important; }
.mwe-math-mathml-display { display: block !important; margin:auto!important;}
}

View File

@ -42,8 +42,9 @@ class MathLaTeXMLTest extends MediaWikiTestCase {
$this->setMwGlobals( 'wgMathLaTeXMLTimeout', 20 );
$this->setMwGlobals( 'wgMathValidModes', array( MW_MATH_LATEXML ) );
$renderer = MathRenderer::getRenderer( "a+b", array(), MW_MATH_LATEXML );
$real = $renderer->render( true );
$expected = '<span class="tex" dir="ltr" id="a_b"><math xmlns="http://www.w3.org/1998/Math/MathML" id="p1.1.m1" class="ltx_Math" alttext="{\displaystyle a+b}" display="inline" xml:id="p1.1.m1.1" xref="p1.1.m1.1.cmml"> <semantics xml:id="p1.1.m1.1a" xref="p1.1.m1.1.cmml"> <mrow xml:id="p1.1.m1.1.4" xref="p1.1.m1.1.4.cmml"> <mi xml:id="p1.1.m1.1.1" xref="p1.1.m1.1.1.cmml">a</mi> <mo xml:id="p1.1.m1.1.2" xref="p1.1.m1.1.2.cmml">+</mo> <mi xml:id="p1.1.m1.1.3" xref="p1.1.m1.1.3.cmml">b</mi> </mrow> <annotation-xml encoding="MathML-Content" xml:id="p1.1.m1.1.cmml" xref="p1.1.m1.1"> <apply xml:id="p1.1.m1.1.4.cmml" xref="p1.1.m1.1.4"> <plus xml:id="p1.1.m1.1.2.cmml" xref="p1.1.m1.1.2"/> <ci xml:id="p1.1.m1.1.1.cmml" xref="p1.1.m1.1.1">a</ci> <ci xml:id="p1.1.m1.1.3.cmml" xref="p1.1.m1.1.3">b</ci> </apply> </annotation-xml> <annotation encoding="application/x-tex" xml:id="p1.1.m1.1b" xref="p1.1.m1.1.cmml">{\displaystyle a+b}</annotation> </semantics> </math></span>';
$renderer->render( true );
$expected = '<span><span class="mwe-math-mathml-inline" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" id="p1.1.m1" class="ltx_Math" alttext="{\displaystyle a+b}" display="inline" xml:id="p1.1.m1.1" xref="p1.1.m1.1.cmml"><semantics xml:id="p1.1.m1.1a" xref="p1.1.m1.1.cmml"><mrow xml:id="p1.1.m1.1.4" xref="p1.1.m1.1.4.cmml"><mi xml:id="p1.1.m1.1.1" xref="p1.1.m1.1.1.cmml">a</mi><mo xml:id="p1.1.m1.1.2" xref="p1.1.m1.1.2.cmml">+</mo><mi xml:id="p1.1.m1.1.3" xref="p1.1.m1.1.3.cmml">b</mi></mrow><annotation-xml encoding="MathML-Content" xml:id="p1.1.m1.1.cmml" xref="p1.1.m1.1"><apply xml:id="p1.1.m1.1.4.cmml" xref="p1.1.m1.1.4"><plus xml:id="p1.1.m1.1.2.cmml" xref="p1.1.m1.1.2"/><ci xml:id="p1.1.m1.1.1.cmml" xref="p1.1.m1.1.1">a</ci><ci xml:id="p1.1.m1.1.3.cmml" xref="p1.1.m1.1.3">b</ci></apply></annotation-xml><annotation encoding="application/x-tex" xml:id="p1.1.m1.1b" xref="p1.1.m1.1.cmml">{\displaystyle a+b}</annotation></semantics></math></span></span>';
$real = preg_replace( "/\n\s*/", '', $renderer->getHtmlOutput() );
$this->assertEquals( $expected, $real
, "Rendering of a+b in plain Text mode." .
$renderer->getLastError() );

View File

@ -27,7 +27,7 @@ class MathRendererTest extends MediaWikiTestCase {
*/
public function testWriteCacheSkip() {
$renderer = $this->getMockBuilder( 'MathRenderer' )
->setMethods( array( 'writeToDatabase' , 'render', 'getMathTableName' ) )
->setMethods( array( 'writeToDatabase' , 'render', 'getMathTableName', 'getHtmlOutput' ) )
->disableOriginalConstructor()
->getMock();
$renderer->expects( $this->never() )
@ -41,7 +41,7 @@ class MathRendererTest extends MediaWikiTestCase {
*/
public function testWriteCache() {
$renderer = $this->getMockBuilder( 'MathRenderer' )
->setMethods( array( 'writeToDatabase' , 'render', 'getMathTableName' ) )
->setMethods( array( 'writeToDatabase' , 'render', 'getMathTableName', 'getHtmlOutput' ) )
->disableOriginalConstructor()
->getMock();
$renderer->expects( $this->never() )
@ -51,7 +51,7 @@ class MathRendererTest extends MediaWikiTestCase {
public function testSetPurge() {
$renderer = $this->getMockBuilder( 'MathRenderer' )
->setMethods( array( 'render', 'getMathTableName' ) )
->setMethods( array( 'render', 'getMathTableName', 'getHtmlOutput' ) )
->disableOriginalConstructor()
->getMock();
$renderer->setPurge();

View File

@ -27,17 +27,13 @@ class MathTexvcTest extends MediaWikiTestCase {
// Create a MathTexvc mock, replacing methods 'readFromDatabase',
// 'callTexvc', and 'doHTMLRender' with test doubles.
$texvc = $this->getMockBuilder( 'MathTexvc' )
->setMethods( array( 'readFromDatabase', 'callTexvc', 'doHTMLRender' ) )
->disableOriginalConstructor()
$texvc = $this->getMockBuilder( 'MathTexvc' )->setMethods( array( 'readFromDatabase', 'callTexvc', 'getHtmlOutput' ) )->disableOriginalConstructor()
->getMock();
// When we call render() below, MathTexvc will ...
// ... first check if the item exists in the database cache:
$texvc->expects( $this->once() )
->method( 'readFromDatabase' )
->with()
$texvc->expects( $this->once() )->method( 'readFromDatabase' )->with()
->will( $this->returnValue( true ) );
// ... if cache lookup succeeded, it won't shell out to texvc:
@ -45,8 +41,7 @@ class MathTexvcTest extends MediaWikiTestCase {
->method( 'callTexvc' );
// ... instead, MathTexvc will skip to HTML generation:
$texvc->expects( $this->once() )
->method( 'doHTMLRender' );
$texvc->expects( $this->once() )->method( 'getHtmlOutput' );
$texvc->render();
}
@ -60,7 +55,7 @@ class MathTexvcTest extends MediaWikiTestCase {
*/
function testRenderCacheMiss() {
$texvc = $this->getMockBuilder( 'MathTexvc' )
->setMethods( array( 'readCache', 'callTexvc', 'doHTMLRender' ) )
->setMethods( array( 'readCache', 'callTexvc', 'getHtmlOutput' ) )
->disableOriginalConstructor()
->getMock();
@ -77,8 +72,7 @@ class MathTexvcTest extends MediaWikiTestCase {
->will( $this->returnValue( MathTexvc::MW_TEXVC_SUCCESS ) );
// ... if texvc succeeds, MathTexvc will generate HTML:
$texvc->expects( $this->once() )
->method( 'doHTMLRender' );
$texvc->expects( $this->once() )->method( 'getHtmlOutput' );
$texvc->render();
}
@ -91,7 +85,7 @@ class MathTexvcTest extends MediaWikiTestCase {
*/
function testRenderTexvcFailure() {
$texvc = $this->getMockBuilder( 'MathTexvc' )
->setMethods( array( 'readCache', 'callTexvc', 'doHTMLRender' ) )
->setMethods( array( 'readCache', 'callTexvc', 'getHtmlOutput' ) )
->disableOriginalConstructor()
->getMock();
@ -104,12 +98,11 @@ class MathTexvcTest extends MediaWikiTestCase {
// ... on cache miss, shell out to texvc:
$texvc->expects( $this->once() )
->method( 'callTexvc' )
->will( $this->returnValue( 'error' ) );
->method( 'callTexvc' )->will( $this->returnValue( 'error' ) );
// ... if texvc fails, render() will not generate HTML:
$texvc->expects( $this->never() )
->method( 'doHTMLRender' );
->method( 'getHtmlOutput' );
// ... it will return the error result instead:
$this->assertEquals( $texvc->render(), 'error' );