forked from wikimedia/mediawiki-extensions-Math
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSpecialMathStatus.php
More file actions
196 lines (179 loc) · 7.73 KB
/
SpecialMathStatus.php
File metadata and controls
196 lines (179 loc) · 7.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
<?php
use MediaWiki\Logger\LoggerFactory;
/**
* MediaWiki math extension
*
* (c) 2002-2015 Tomasz Wegrzanowski, Brion Vibber, Moritz Schubotz,
* and other MediaWiki contributors
* GPLv2 license; info in main package.
*
* @author Moritz Schubotz
*/
class SpecialMathStatus extends SpecialPage {
public function __construct( $name = 'MathStatus' ) {
parent::__construct( $name );
}
/**
* @param null|string $query
*
* @throws MWException
* @throws PermissionsError
*/
function execute( $query ) {
$this->setHeaders();
if ( ! ( $this->getUser()->isAllowed( 'purge' ) ) ) {
// The effect of loading this page is comparable to purge a page.
// If desired a dedicated right e.g. "viewmathstatus" could be used instead.
throw new PermissionsError( 'purge' );
}
$out = $this->getOutput();
$enabledMathModes = MathHooks::getMathNames();
$out->addWikiMsg( 'math-status-introduction', count( $enabledMathModes ) );
foreach ( $enabledMathModes as $modeNr => $modeName ){
$out->addWikiText( "=== $modeName ===" );
switch ( $modeNr ) {
case 'mathml':
$this->runMathMLTest( $modeName );
break;
case 'latexml':
$this->runMathLaTeXMLTest( $modeName );
}
}
}
private function runMathMLTest( $modeName ) {
$this->getOutput()->addWikiMsgArray( 'math-test-start', $modeName );
$this->testSpecialCaseText();
$this->testMathMLIntegration();
$this->testPmmlInput();
$this->getOutput()->addWikiMsgArray( 'math-test-end', $modeName );
}
private function runMathLaTeXMLTest( $modeName ) {
$this->getOutput()->addWikiMsgArray( 'math-test-start', $modeName );
$this->testLaTeXMLIntegration();
$this->testLaTeXMLLinebreak();
$this->getOutput()->addWikiMsgArray( 'math-test-end', $modeName );
}
public function testSpecialCaseText() {
$renderer = MathRenderer::getRenderer( 'x^2+\text{a sample Text}', [], 'mathml' );
$expected = 'a sample Text</mtext>';
$this->assertTrue( $renderer->render(), 'Rendering the input "x^2+\text{a sample Text}"' );
$this->assertContains(
$expected, $renderer->getHtmlOutput(), 'Comparing to the reference rendering'
);
}
/**
* Checks the basic functionality
* i.e. if the span element is generated right.
*/
public function testMathMLIntegration() {
$svgRef = file_get_contents( __DIR__ .'/images/reference.svg' );
$svgRefNoSpeech = file_get_contents( __DIR__ .'/images/reference-nospeech.svg' );
$renderer = MathRenderer::getRenderer( "a+b", [], 'mathml' );
$this->assertTrue( $renderer->render( true ), "Rendering of a+b in plain MathML mode" );
$real = str_replace( "\n", '', $renderer->getHtmlOutput() );
$expected = '<mo>+</mo>';
$this->assertContains( $expected, $real, "Checking the presence of '+' in the MathML output" );
$this->assertEquals( [ $svgRef, $svgRefNoSpeech ], $renderer->getSvg(),
"Comparing the generated SVG with the reference"
);
}
/**
* Checks the experimental option to 'render' MathML input
*/
public function testPmmlInput() {
// sample from 'Navajo Coal Combustion and Respiratory Health Near Shiprock,
// New Mexico' in ''Journal of Environmental and Public Health'' , vol. 2010p.
// authors Joseph E. Bunnell; Linda V. Garcia; Jill M. Furst;
// Harry Lerch; Ricardo A. Olea; Stephen E. Suitt; Allan Kolker
// @codingStandardsIgnoreStart
$inputSample = '<msub> <mrow> <mi> P</mi> </mrow> <mrow> <mi> i</mi> <mi> j</mi> </mrow> </msub> <mo> =</mo> <mfrac> <mrow> <mn> 100</mn> <msub> <mrow> <mi> d</mi> </mrow> <mrow> <mi> i</mi> <mi> j</mi> </mrow> </msub> </mrow> <mrow> <mn> 6.75</mn> <msub> <mrow> <mi> r</mi> </mrow> <mrow> <mi> j</mi> </mrow> </msub> </mrow> </mfrac> <mo> ,</mo> </math>';
// @codingStandardsIgnoreEnd
$attribs = [ 'type' => 'pmml' ];
$renderer = new MathMathML( $inputSample, $attribs );
$this->assertEquals( 'pmml', $renderer->getInputType(), 'Checking if MathML input is supported' );
$this->assertTrue( $renderer->render(), 'Rendering Presentation MathML sample' );
$real = MathRenderer::renderMath( $inputSample, $attribs, 'mathml' );
$expected = 'hash=5628b8248b79267ecac656102334d5e3&mode=mathml';
$this->assertContains( $expected, $real, 'Checking if the link to SVG image is correct' );
}
/**
* Checks the basic functionality
* i.e. if the span element is generated right.
*/
public function testLaTeXMLIntegration() {
$renderer = MathRenderer::getRenderer( "a+b", [], 'latexml' );
$this->assertTrue( $renderer->render( true ), "Rendering of a+b in LaTeXML mode" );
// @codingStandardsIgnoreStart
$expected = '<math xmlns="http://www.w3.org/1998/Math/MathML" id="p1.m1" class="ltx_Math" alttext="{\displaystyle a+b}" ><semantics><mrow id="p1.m1.4" xref="p1.m1.4.cmml"><mi id="p1.m1.1" xref="p1.m1.1.cmml">a</mi><mo id="p1.m1.2" xref="p1.m1.2.cmml">+</mo><mi id="p1.m1.3" xref="p1.m1.3.cmml">b</mi></mrow><annotation-xml encoding="MathML-Content"><apply id="p1.m1.4.cmml" xref="p1.m1.4"><plus id="p1.m1.2.cmml" xref="p1.m1.2"/><ci id="p1.m1.1.cmml" xref="p1.m1.1">a</ci><ci id="p1.m1.3.cmml" xref="p1.m1.3">b</ci></apply></annotation-xml><annotation encoding="application/x-tex">{\displaystyle a+b}</annotation></semantics></math>';
// @codingStandardsIgnoreEnd
$real = preg_replace( "/\n\\s*/", '', $renderer->getHtmlOutput() );
$this->assertContains( $expected, $real,
"Comparing the output to the MathML reference rendering" .
$renderer->getLastError() );
}
/**
* Checks LaTeXML line break functionality
* i.e. if a long line contains a mtr element.
* http://www.w3.org/TR/REC-MathML/chap3_5.html#sec3.5.2
*/
public function testLaTeXMLLinebreak() {
global $wgMathDefaultLaTeXMLSetting;
$tex = '';
$testMax = ceil( $wgMathDefaultLaTeXMLSetting[ 'linelength' ] / 2 );
for ( $i = 0; $i < $testMax; $i++ ) {
$tex .= "$i+";
}
$tex .= $testMax;
$renderer = new MathLaTeXML( $tex, [ 'display' => 'linebreak' ] );
$this->assertTrue( $renderer->render( true ), "Rendering of linebreak test in LaTeXML mode" );
$expected = 'mtr';
$real = preg_replace( "/\n\\s*/", '', $renderer->getHtmlOutput() );
$this->assertContains( $expected, $real, "Checking for linebreak" .
$renderer->getLastError() );
}
private function assertTrue( $expression, $message = '' ) {
if ( $expression ){
$this->getOutput()->addWikiMsgArray( 'math-test-success', $message );
return true;
} else {
$this->getOutput()->addWikiMsgArray( 'math-test-fail', $message );
return false;
}
}
private function assertContains( $expected, $real, $message = '' ) {
if ( ! $this->assertTrue( strpos( $real, $expected ) !== false, $message ) ) {
$this->printDiff( $expected, $real, 'math-test-contains-diff' );
}
}
private function assertEquals( $expected, $real, $message = '' ) {
if ( is_array( $expected ) ) {
foreach ( $expected as $alternative ){
if ( $alternative === $real ) {
$this->getOutput()->addWikiMsgArray( 'math-test-success', $message );
return true;
}
}
// non of the alternatives matched
$this->getOutput()->addWikiMsgArray( 'math-test-fail', $message );
return false;
}
if ( !$this->assertTrue( $expected === $real, $message ) ) {
$this->printDiff( $expected, $real, 'math-test-equals-diff' );
return false;
}
return true;
}
private function printDiff( $expected, $real, $message = '' ) {
if ( ExtensionRegistry::getInstance()->isLoaded( "SyntaxHighlight" ) ) {
$expected = "<syntaxhighlight lang=\"xml\">$expected</syntaxhighlight>";
$real = "<syntaxhighlight lang=\"xml\">$real</syntaxhighlight>";
$this->getOutput()->addWikiMsgArray( $message, [ $real, $expected ] );
} else {
LoggerFactory::getInstance( 'Math' )->warning( 'Can not display expected and real value.'.
'SyntaxHighlight is not installed.' );
}
}
protected function getGroupName() {
return 'other';
}
}