Fix: Allow <div /> as valid Math output

Some simple math tags such as the rendering result of
$\mathcal{ABC}$
are converted to an HTML-div tag by LaTeXML if inline-mode
is used. This change
* makes the $wgMathDefaultLaTeXMLSetting easier to read
* improves the XML validation of the LaTeXML output.

Change-Id: I807dbfa3a45930deec8eb5615133be9a39f3f101
This commit is contained in:
Moritz Schubotz (Physikerwelt) 2014-04-08 10:39:12 +00:00 committed by Physikerwelt
parent 58f913ecb0
commit 3a36b25ee3
4 changed files with 85 additions and 15 deletions

View File

@ -143,7 +143,26 @@ $wgMathLaTeXMLTimeout = 240;
* Setting for the LaTeXML renderer.
* See http://dlmf.nist.gov/LaTeXML/manual/commands/latexmlpost.xhtml for details.
*/
$wgMathDefaultLaTeXMLSetting = 'format=xhtml&whatsin=math&whatsout=math&pmml&cmml&nodefaultresources&preload=LaTeX.pool&preload=article.cls&preload=amsmath.sty&preload=amsthm.sty&preload=amstext.sty&preload=amssymb.sty&preload=eucal.sty&preload=[dvipsnames]xcolor.sty&preload=url.sty&preload=hyperref.sty&preload=[ids]latexml.sty&preload=texvc';
$wgMathDefaultLaTeXMLSetting = array(
'format' => 'xhtml',
'whatsin' => 'math',
'whatsout' => 'math',
'pmml',
'cmml',
'nodefaultresources',
'preload' => array( 'LaTeX.pool',
'article.cls',
'amsmath.sty',
'amsthm.sty',
'amstext.sty',
'amssymb.sty',
'eucal.sty',
'[dvipsnames]xcolor.sty',
'url.sty',
'hyperref.sty',
'[ids]latexml.sty',
'texvc' ),
);
/**
* The link to the texvccheck executable
*/

View File

@ -15,6 +15,10 @@ class MathLaTeXML extends MathRenderer {
* @var String settings for LaTeXML daemon
*/
private $LaTeXMLSettings = '';
/** @var boolean if false LaTeXML output is not validated */
private $XMLValidation = true;
protected static $DEFAULT_ALLOWED_ROOT_ELEMENTS = array( 'math', 'div', 'table', 'query' );
protected $allowedRootElements = '';
/**
* Converts an array with LaTeXML settings to a URL encoded String.
@ -30,12 +34,15 @@ class MathLaTeXML extends MathRenderer {
// removes the [1] [2]... for the unnamed subarrays since LaTeXML
// assigns multiple values to one key e.g.
// preload=amsmath.sty&preload=amsthm.sty&preload=amstext.sty
return preg_replace( '|\%5B\d+\%5D|', '', wfArrayToCgi( $array ) ) ;
$cgi_string = wfArrayToCgi( $array );
$cgi_string = preg_replace( '|\%5B\d+\%5D|', '', $cgi_string );
$cgi_string = preg_replace( '|&\d+=|', '&', $cgi_string );
return $cgi_string;
}
}
/**
* Gets the settings for the LaTeXML daemon.
* @global type $wgMathDefaultLaTeXMLSetting
* @global (array|string) $wgMathDefaultLaTeXMLSetting
* @return string
*/
public function getLaTeXMLSettings() {
@ -59,6 +66,28 @@ class MathLaTeXML extends MathRenderer {
$this->LaTeXMLSettings = $settings;
}
/**
* 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;
}
/* (non-PHPdoc)
* @see MathRenderer::render()
*/
@ -90,7 +119,7 @@ class MathLaTeXML extends MathRenderer {
} else {
$dbres = $this->readFromDatabase();
if ( $dbres ) {
if ( self::isValidMathML( $this->getMathml() ) ) {
if ( $this->isValidMathML( $this->getMathml() ) ) {
wfDebugLog( "Math", "Valid entry found in database." );
return false;
} else {
@ -110,7 +139,7 @@ class MathLaTeXML extends MathRenderer {
* Generates error messages on failure
* @see Http::post()
*
* @global type $wgMathLaTeXMLTimeout
* @global int $wgMathLaTeXMLTimeout
* @param string $host
* @param string $post the encoded post request
* @param mixed $res the result
@ -125,6 +154,7 @@ class MathLaTeXML extends MathRenderer {
$error = '';
$res = null;
$options = array( 'method' => 'POST', 'postData' => $post, 'timeout' => $wgMathLaTeXMLTimeout );
/** @var $req (CurlHttpRequest|PhpHttpRequest) the request object */
$req = $httpRequestClass::factory( $host, $options );
$status = $req->execute();
if ( $status->isGood() ) {
@ -208,7 +238,7 @@ class MathLaTeXML extends MathRenderer {
if ( $this->makeRequest( $host, $post, $res, $this->lastError ) ) {
$result = json_decode( $res );
if ( json_last_error() === JSON_ERROR_NONE ) {
if ( self::isValidMathML( $result->result ) ) {
if ( $this->isValidMathML( $result->result ) ) {
$this->setMathml( $result->result );
wfProfileOut( __METHOD__ );
return true;
@ -237,31 +267,48 @@ class MathLaTeXML extends MathRenderer {
}
}
/**
* Sets the XML validation.
* If set to false the output of LaTeXML is not validated.
* @param boolean $validation
*/
public function setXMLValidation( $validation = true ) {
$this->XMLValidation = $validation;
}
/**
* Checks if the input is valid MathML,
* and if the root element has the name math
* @param string $XML
* @return boolean
*/
static public function isValidMathML( $XML ) {
public function isValidMathML( $XML ) {
$out = false;
if ( !$this->XMLValidation ) {
return true;
}
// depends on https://gerrit.wikimedia.org/r/#/c/66365/
if ( ! is_callable( 'XmlTypeCheck::newFromString' ) ) {
if ( !is_callable( 'XmlTypeCheck::newFromString' ) ) {
$msg = wfMessage( 'math_latexml_xmlversion' )->inContentLanguage()->escaped();
trigger_error( $msg, E_USER_NOTICE );
wfDebugLog( 'Math', $msg );
return true;
}
$xmlObject = new XmlTypeCheck( $XML, null, false );
if ( ! $xmlObject->wellFormed ) {
if ( !$xmlObject->wellFormed ) {
wfDebugLog( "Math", "XML validation error:\n " . var_export( $XML, true ) . "\n" );
} else {
$name = $xmlObject->getRootElement();
$name = str_replace( 'http://www.w3.org/1998/Math/MathML:', '', $name );
if ( $name == "math" or $name == "table" or $name == "div" ) {
$elementSplit = explode( ':', $name );
if ( is_array($elementSplit) ){
$localName = end( $elementSplit );
} else {
$localName = $name;
}
if ( in_array( $localName , $this->getAllowedRootElements() ) ) {
$out = true;
} else {
wfDebugLog( "Math", "got wrong root element " . $name );
wfDebugLog( "Math", "got wrong root element : $name" );
}
}
return $out;

View File

@ -29,7 +29,7 @@ class MathGenerateTests extends Maintenance
{
parent::__construct();
$this->mDescription = 'Rebuilds the MathCoverage tests';
$this->addArg( 'page', "The page ues for the testset generation.", false );
$this->addArg( 'page', "The page used for the testset generation.", false );
$this->addOption( 'offset', "If set the first n equations on the page are skipped", false, true, "o" );
$this->addOption( 'length', "If set the only n equations were processed", false, true, "l" );
$this->addOption( 'user', "User with rights to view the page", false, true, "u" );

View File

@ -97,12 +97,16 @@ class MathLaTeXMLTest extends MediaWikiTestCase {
public function testisValidXML() {
$validSample = '<math>content</math>';
$invalidSample = '<notmath />';
$renderer = $this->getMockBuilder( 'MathLaTeXML' )
->setMethods( NULL ) // avoid mocking any methods
->disableOriginalConstructor()
->getMock();
$this->assertTrue(
MathLaTeXML::isValidMathML( $validSample ),
$renderer->isValidMathML( $validSample ),
'test if math expression is valid mathml sample'
);
$this->assertFalse(
MathLaTeXML::isValidMathML( $invalidSample ),
$renderer->isValidMathML( $invalidSample ),
'test if math expression is invalid mathml sample'
);
}