jenkins-bot has submitted this change and it was merged.

Change subject: Translate LaTeX to corresponding Mathematica
......................................................................


Translate LaTeX to corresponding Mathematica

Add a new Specialpage where users can specifiy LaTeX input that
is translated to the equivalent Mathematica expression.
This mock up works only in selected cases.
If an expression can not be translated the original LaTeX
code is passed unmodified to the output.

Change-Id: Ie5ef7ee76c9a9daa1b3c42a007914f8f1b9a6d2e
---
M MathSearch.alias.php
M MathSearch.php
M i18n/en.json
M i18n/qqq.json
A includes/LaTeXTranslator.php
A includes/special/SpecialLaTeXTranslator.php
A tests/LaTeX2MathematicaTest.php
A tests/tex2nb.json
8 files changed, 1,063 insertions(+), 2 deletions(-)

Approvals:
  Physikerwelt: Looks good to me, approved
  Raimond Spekking: Looks good to me, but someone else must approve
  jenkins-bot: Verified



diff --git a/MathSearch.alias.php b/MathSearch.alias.php
index 8763605..73cd9ba 100644
--- a/MathSearch.alias.php
+++ b/MathSearch.alias.php
@@ -18,6 +18,7 @@
        'MathIndex' => array( 'MathIndex', 'Math Index' ),
        'MathUpload' => array( 'MathUpload', 'Math Upload' ),
        'MathDownload' => array( 'MathDownload', 'Math Download' ),
+       'LaTeXTranslator' => array( 'LaTeXTranslator', 'LaTeX Translator' ),
 );
 
 /** Arabic (العربية) */
diff --git a/MathSearch.php b/MathSearch.php
index 763dc20..efd1b80 100644
--- a/MathSearch.php
+++ b/MathSearch.php
@@ -49,6 +49,8 @@
 $wgAutoloadClasses['MathSearchUtils'] = __DIR__ . 
'/includes/MathSearchUtils.php';
 $wgAutoloadClasses['MathSearchTerm'] = __DIR__ . 
'/includes/MathSearchTerm.php';
 $wgAutoloadClasses['MwsDumpWriter'] = __DIR__ . '/includes/MwsDumpWriter.php';
+$wgAutoloadClasses['SpecialLaTeXTranslator'] = __DIR__ . 
'/includes/special/SpecialLaTeXTranslator.php';
+$wgAutoloadClasses['LaTeXTranslator'] = __DIR__ . 
'/includes/LaTeXTranslator.php';
 
 $wgMessagesDirs['MathSeach'] = __DIR__ . '/i18n';
 $wgExtensionMessagesFiles['MathSearchAlias'] = __DIR__ . 
'/MathSearch.alias.php';
@@ -60,6 +62,7 @@
 $wgSpecialPageGroups['MathDebug'] = 'mathsearch';
 $wgSpecialPageGroups['MathIndex'] = 'mathsearch';
 $wgSpecialPageGroups['DisplayTopics'] = 'mathsearch';
+$wgSpecialPageGroups['SpecialLaTeXTranslator'] = 'mathsearch';
 
 $wgSpecialPages['MathSearch'] = 'SpecialMathSearch';
 $wgSpecialPages['FormulaInfo'] = 'FormulaInfo';
@@ -67,6 +70,7 @@
 $wgSpecialPages['MathDebug'] = 'SpecialMathDebug';
 $wgSpecialPages['MathIndex'] = 'SpecialMathIndex';
 $wgSpecialPages['DisplayTopics'] = 'SpecialDisplayTopics';
+$wgSpecialPages['LaTeXTranslator'] = 'SpecialLaTeXTranslator';
 
 $wgHooks['LoadExtensionSchemaUpdates'][] = 
'MathSearchHooks::onLoadExtensionSchemaUpdates';
 $wgHooks['MathFormulaPostRender']['updateIndex'] = 
'MathSearchHooks::updateMathIndex';
diff --git a/i18n/en.json b/i18n/en.json
index e1762f6..108dc82 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -9,6 +9,7 @@
        "mathdownload": "Download math search results",
        "mathindex": "Math index",
        "mathupload": "Submit math search results",
+       "latextranslator": "LaTeX to Mathematica Translator",
        "specialpages-group-mathsearch": "Math search",
        "mathsearch-desc": "Integrates the 
[http://search.mathweb.org/about.html MathWeb Search] engine",
        "getequationsbyquery": "Get equations by query",
@@ -56,5 +57,10 @@
        "math-search-type-0": "Keyword",
        "math-search-type-1": "TeX pattern",
        "math-search-type-2": "xQuery expression",
-       "math-search-expression-label": "Expression:"
+       "math-search-expression-label": "Expression:",
+       "math-tex2nb-header": "Specify your own input below",
+       "math-tex2nb-intro": "This mock up is supposed to demonstrate the idea 
of TeX to Mathematica conversion.\n\nThe demo-application converts LaTeX 
functions which directly translate to Mathematica counterparts.\n\nFunctions 
without explicit Mathematica support are available for translation via a DRMF 
package (under development).",
+       "math-tex2nb-input": "Input",
+       "math-tex2nb-latex": "The following LaTeX input ...",
+       "math-tex2nb-mathematica": "... is translated to the Mathematica output 
..."
 }
\ No newline at end of file
diff --git a/i18n/qqq.json b/i18n/qqq.json
index d80f7d6..d2032ee 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -18,6 +18,7 @@
        "getequationsbyquery": "{{doc-special|GetEquationByQuery}}",
        "xquerygenerator": "{{doc-special|XQueryGenerator}}",
        "mathdebug": "{{doc-special|MathDebug}}",
+       "latextranslator": "{{doc-special|LaTeX to Mathematica Translator}}",
        "math-wmc-attach-results-help": "Form label help text",
        "math-wmc-attach-results-label": "Form label",
        "math-wmc-download-intro": "Introductory text for MathDownload special 
page.",
@@ -51,5 +52,10 @@
        "math-search-type-0": "First option in type selection menu and part of 
{{msg-mw|math-search-term}}\n{{Identical|Keyword}}",
        "math-search-type-1": "Section option in type selection menu and part 
of {{msg-mw|math-search-term}}",
        "math-search-type-2": "Section option in type selection menu and part 
of {{msg-mw|math-search-term}}",
-       "math-search-expression-label": "Text form 
label\n{{Identical|Expression}}"
+       "math-search-expression-label": "Text form 
label\n{{Identical|Expression}}",
+       "math-tex2nb-intro": "Introductory text for the specialpage 
LaTeXTranslator.",
+       "math-tex2nb-input": "Form label for the LaTeX input form on the 
specialpage LaTeXTranslator.",
+       "math-tex2nb-latex": "Message above the syntax-highlighted-LaTeX input 
on the specialpage LaTeXTranslator.",
+       "math-tex2nb-mathematica": "Message between the LaTex input and the 
output on the specialpage LaTeXTranslator.",
+       "math-tex2nb-header": "Header of the input-box for user-defined LaTeX 
input on the specialpage LaTeXTranslator."
 }
diff --git a/includes/LaTeXTranslator.php b/includes/LaTeXTranslator.php
new file mode 100644
index 0000000..abf6df2
--- /dev/null
+++ b/includes/LaTeXTranslator.php
@@ -0,0 +1,712 @@
+<?php
+
+class LaTeXTranslator {
+       private $replacements;
+
+       /**
+        * @var string contains frequently occurring regex for recurisve 
extraction of nested parenthesis
+        */
+       private $par = "(\\{(?>[^{}]|(?-1))*\\})";
+       /**
+        * @var string contains frequently occurring regex for single argument 
of number or Greek letter
+        */
+       private $arg = "(\\\\[?[A-z]*\\]?|[0-9]|[A-z]{1})";
+
+       function __construct() {
+               # reference: http://stackoverflow.com/a/28611214/4521584
+               $this->replacements = array(
+                       array(
+                               # Trignometric & Trig Integrals: \acosh@{x}
+                               'search' =>
+                                       
"~\\\\(a?(?>cos|sin|tan|csc|cot|sec)h?)(int)?@{0,2}(" . $this->arg . "|" .
+                                       $this->par . ")~i",
+                               # Trignometric: ArcCosh[x]
+                               'replace' => function ( array $m ) {
+                                       return ( $m[1][0] == 'a' ? 'Arc' . 
ucfirst( strtolower( substr( $m[1], 1 ) ) )
+                                               : ucfirst( strtolower( $m[1] ) 
) ) .
+                                                  ( strlen( $m[2] ) > 0 ? 
'Integral' : '' ) . '[' .
+                                                  LaTeXTranslator::brackR( 
$m[3] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Logarithm
+                               'search' =>
+                                       "~\\\\(?>log|ln)b?" . $this->par . 
"?@{0,2}(" . $this->arg . "|" . $this->par .
+                                       ")~i",
+                               # Logarithm: Log[x]
+                               'replace' => function ( array $m ) {
+                                       return 'Log[' . ( strlen( $m[1] ) > 0 ? 
$m[1] . ',' : '' ) .
+                                                  LaTeXTranslator::brackR( 
$m[2] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Airy: \AiryAi@{z}
+                               'search' => "~\\\\Airy([B|A]i)@{0,2}(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Airy: AiryAi[z]
+                               'replace' => function ( array $m ) {
+                                       return 'Airy' . $m[1] . '[' . 
LaTeXTranslator::brackR( $m[2] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Airy Modulus M: \AiryModulusM@{z}
+                               'search' => "~\\\\AiryModulusM@{0,2}(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Airy Modulus M: Sqrt[AiryAi[x]^2+AiryBi[x]^2]
+                               'replace' => function ( array $m ) {
+                                       return 'Sqrt[AiryAi[' . 
LaTeXTranslator::brackR( $m[1] ) . ']^2+AiryBi[' .
+                                                  LaTeXTranslator::brackR( 
$m[1] ) . ']^2]';
+                               }
+                       ),
+                       array(
+                               # Arithmetic Geometric Mean: \AGM@{a}{g}
+                               'search' =>
+                                       "~\\\\AGM@{0,2}(" . $this->arg . "|" . 
$this->par . ")(" . $this->arg . "|" .
+                                       $this->par . ")~i",
+                               # Arithmetic Geometric Mean: 
ArithmeticGeometricMean[a,b]
+                               'replace' => function ( array $m ) {
+                                       return 'ArithmeticGeometricMean[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' .
+                                                  LaTeXTranslator::brackR( 
$m[4] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Anger: \AngerJ{\nu}@{z}
+                               'search' => "~\\\\AngerJ" . $this->par . 
"@{0,2}(" . $this->arg . "|" . $this->par .
+                                                       ")~i",
+                               # Anger: AngerJ[\nu,z]
+                               'replace' => function ( array $m ) {
+                                       return 'AngerJ[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' . LaTeXTranslator::brackR( $m[2] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Appell: 
\AppellFi@{\alpha}{\beta}{\beta'}{\gamma}{x}{y}
+                               'search' => "~\\\\AppellF[i{1,3}v?]@{0,2}(" . 
$this->arg . "|" . $this->par . ")(" .
+                                                       $this->arg . "|" . 
$this->par . ")(" . $this->arg . "|" . $this->par .
+                                                       ")(" . $this->arg . "|" 
. $this->par . ")(" . $this->arg . "|" .
+                                                       $this->par . ")(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Appell: 
AppellF1[\alpha,\beta,\beta',\gamma,x,y]
+                               'replace' => function ( array $m ) {
+                                       return
+                                               'AppellF1[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' . LaTeXTranslator::brackR( $m[4] ) . ',' 
.
+                                               LaTeXTranslator::brackR( $m[7] 
) . ',' . LaTeXTranslator::brackR( $m[10] ) . ',' .
+                                               LaTeXTranslator::brackR( $m[13] 
) . ',' . LaTeXTranslator::brackR( $m['16'] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Barnes G: \BarnesGamma@{z}
+                               'search' => "~\\\\BarnesGamma@{0,2}(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Barnes G: BarnesG[z]
+                               'replace' => function ( array $m ) {
+                                       return 'BarnesG[' . 
LaTeXTranslator::brackR( $m[1] ) . ']';
+                               }
+                       ),
+                       array(
+                               # BesselJ: \BesselJ{n}@{z}  - default?? for 
BesselJ{nu}/Cheby w/ no z???
+                               'search' => "~\\\\Bessel([A-Z])" . $this->par . 
"@?(" . $this->par . ")?~i",
+                               # BesselJ: BesselJ[n,z]
+                               'replace' => function ( array $m ) {
+                                       return 'Bessel' . $m[1] . '[' . 
LaTeXTranslator::brackR( $m[2] ) .
+                                                  ( strlen( $m[3] ) > 0 ? ',' 
. LaTeXTranslator::brackR( $m[3] ) : ',0' ) . ']';
+                               }
+                       ),
+                       array(
+                               # Binomial Coefficient: \binomial{m}{n}
+                               'search' => "~\\\\binom(?>ial)?@{0,2}" . 
$this->par . $this->par . "~i",
+                               # Binomial Coefficient: Binomial[n,m]
+                               'replace' => function ( array $m ) {
+                                       return 'Binomial[' . 
LaTeXTranslator::brackR( $m[2] ) . ',' . LaTeXTranslator::brackR( $m[1] ) .
+                                                  ']';
+                               }
+                       ),
+                       array(
+                               # Catalan Number: \CatalanNumber@{n}
+                               'search' => "~\\\\CatalanNumber@{0,2}(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Catalan Number: CatalanNumber[n]
+                               'replace' => function ( array $m ) {
+                                       return 'CatalanNumber[' . 
LaTeXTranslator::brackR( $m[1] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Ceiling: \ceiling{x}
+                               'search' => "~\\\\ceiling@{0,2}(" . $this->arg 
. "|" . $this->par . ")~i",
+                               # Ceiling: Ceiling[x]
+                               'replace' => function ( array $m ) {
+                                       return 'Ceiling[' . 
LaTeXTranslator::brackR( $m[1] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Chebyshev: \ChebyT{x}@{n}
+                               'search' => "~\\\Cheby([A-Z])" . $this->par . 
"@?(" . $this->par . ")?~i",
+                               # Chebyshev: ChebyshevT[n,x]
+                               'replace' => function ( array $m ) {
+                                       return 'Chebyshev' . $m[1] . '[' . 
LaTeXTranslator::brackR( $m[2] ) .
+                                                  ( strlen( $m[3] ) > 0 ? ',' 
. LaTeXTranslator::brackR( $m[3] ) : ',0' ) . ']';
+                               }
+                       ),
+                       array(
+                               # Complex Conjugate: \conj{z}
+                               'search' => "~\\\\conj@{0,2}" . $this->par . 
"~i",
+                               # Complex Conjugate: Conjugate[z]
+                               'replace' => function ( array $m ) {
+                                       return 'Conjugate[' . 
LaTeXTranslator::brackR( $m[1] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Cylinder: \Cylinder{\nu}@{z}
+                               'search' =>
+                                       "~\\\\Cylinder" . $this->par . 
"@{0,2}(" . $this->arg . "|" . $this->par .
+                                       ")~i",
+                               # Cylinder: ParabolicCylinderD[\nu,z]
+                               'replace' => function ( array $m ) {
+                                       return 'ParabolicCylinderD[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' .
+                                                  LaTeXTranslator::brackR( 
$m[2] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Dawson's Integral: \DawsonsInt@{z}
+                               'search' => "~\\\DawsonsInt@{0,2}(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Dawsons Integral: DawsonF[z]
+                               'replace' => function ( array $m ) {
+                                       return 'DawsonF[' . 
LaTeXTranslator::brackR( $m[1] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Dedekind's Eta: \DedekindModularEta@{\tau}
+                               'search' => "~\\\\DedekindModularEta@{0,2}(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Dedekind's Eta: DedekindEta[\tau]
+                               'replace' => function ( array $m ) {
+                                       return 'DedekindEta[' . 
LaTeXTranslator::brackR( $m[1] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Derivative: \deriv{f}{x}
+                               'search' => "~\\\\p?deriv@{0,2}" . $this->par . 
$this->par . "~i",
+                               # Derivative: D[f,x]
+                               'replace' => function ( array $m ) {
+                                       return 'D[' . LaTeXTranslator::brackR( 
$m[1] ) . ',' . LaTeXTranslator::brackR( $m[2] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Determinant: \det
+                               'search' => "~\\\\det@{0,2}(" . $this->arg . 
"|" . $this->par . ")~i",
+                               # Determinant: Det[a]
+                               'replace' => function ( array $m ) { return 
'Det[' . $m[1] . ']'; }
+                       ),
+                       array(
+                               # Divergence: \divergence
+                               'search' => "~\\\\divergence@{0,2}(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Divergence: divergence
+                               'replace' => function ( array $m ) { return 
'Div[' . $m[1] . ']'; }
+                       ),
+                       array(
+                               # Elliptic Integral: \CompEllIntC@{a}
+                               'search' =>
+                                       
"~\\\\(?>Comp)?EllInt[C]?([A-Z]|Pi)@{0,3}(" . $this->arg . "|" . $this->par .
+                                       ")(" . $this->arg . "|" . $this->par . 
")?~i",
+                               # Elliptic Integral: EllipticC[x, Sqrt[m]]
+                               'replace' => function ( array $m ) {
+                                       return 'Elliptic' . $m[1] . '[' . ( 
sizeof( $m ) > 5 ?
+                                               LaTeXTranslator::brackR( $m[2] 
) . ', Sqrt[' . LaTeXTranslator::brackR( $m[4] ) . ']'
+                                               : 'Sqrt[' . 
LaTeXTranslator::brackR( $m[2] ) . ']' ) . ']';
+                               }
+                       ),
+                       array(
+                               # Error: \erf@{z}
+                               'search' => "~\\\\erf[a-z]?@{0,2}(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Error: Erf[z]
+                               'replace' => function ( array $m ) { return 
'Erf[' . LaTeXTranslator::brackR( $m[1] ) . ']'; }
+                       ),
+                       array(
+                               # Euler Beta & Gamma: \EulerBeta@{a}{b}
+                               'search' => "~\\\\Euler(Beta|Gamma)@{0,2}(" . 
$this->arg . "|" . $this->par . ")(" .
+                                                       $this->arg . "|" . 
$this->par . ")?~i",
+                               # Euler Beta & Gamma: Beta[a,b]
+                               'replace' => function ( array $m ) {
+                                       return $m[1] . '[' . 
LaTeXTranslator::brackR( $m[2] ) .
+                                                  ( strlen( $m[5] ) > 0 && 
strtolower( $m[1] ) == 'beta' ?
+                                                          ',' . 
LaTeXTranslator::brackR( $m[5] ) : '' ) . ']';
+                               }
+                       ),
+                       array(
+                               # Exponential: \exp@{x}
+                               'search' => "~\\\\exp@{0,2}(" . $this->arg . 
"|" . $this->par . ")~i",
+                               # Exponential: Exp[x]
+                               'replace' => function ( array $m ) { return 
'Exp[' . LaTeXTranslator::brackR( $m[1] ) . ']'; }
+                       ),
+                       array(
+                               # Exponential Integral: \ExpInti@{x}
+                               'search' => "~\\\\ExpInt([a-z])?" . $this->par 
. "?@{0,2}(" . $this->arg . "|" .
+                                                       $this->par . ")~i",
+                               # Exponential Integral: ExpIntegralEi[z]
+                               'replace' => function ( array $m ) {
+                                       return 'ExpIntegralE' . ( $m[1] == 'i' 
? 'i' : '' ) . '[' .
+                                                  ( strlen( $m[2] ) > 0 ? 
LaTeXTranslator::brackR( $m[2] ) . ',' : '' ) .
+                                                  LaTeXTranslator::brackR( 
$m[3] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Floor: \floor{x}
+                               'search' => "~\\\\floor(" . $this->arg . "|" . 
$this->par . ")~i",
+                               # Floor: Floor[x]
+                               'replace' => function ( array $m ) {
+                                       return 'Floor[' . 
LaTeXTranslator::brackR( $m[1] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Fraction: \frac{a}{b}
+                               'search' => "~\\\\frac(" . $this->arg . "|" . 
$this->par . ")(" . $this->arg . "|" .
+                                                       $this->par . ")~i",
+                               # Fraction: a/b
+                               'replace' => function ( array $m ) {
+                                       return ( strlen( $m[3] ) > 0 ? '(' . 
LaTeXTranslator::brackR( $m[1] ) . ')'
+                                               : LaTeXTranslator::brackR( 
$m[1] ) ) . '/' .
+                                                  ( sizeof( $m ) > 6 ? '(' . 
LaTeXTranslator::brackR( $m[4] ) . ')'
+                                                          : 
LaTeXTranslator::brackR( $m[4] ) );
+                               }
+                       ),
+                       array(
+                               # Fresnel: \FresnelSin@{z}
+                               'search' => "~\\\\Fresnel([a-z]*)@{0,2}(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Fresnel: FresnelS[z]
+                               'replace' => function ( array $m ) {
+                                       return 'Fresnel' . ucfirst( $m[1][0] ) 
. '[' . LaTeXTranslator::brackR( $m[2] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Greek Letter: \Alpha
+                               'search' => 
"~\\\\(alpha|beta|gamma|delta|epsilon|varepsilon|zeta|eta|theta|vartheta|gamma|kappa|lambda|mu|nu|xi|o[^mega]|pi|varpi|rho|varrho|sigma|varsigma|tau|upsilon|phi|varphi|chi|psi|omega)~i",
+                               # Greek Letter: \[CapitalAlpha]
+                               'replace' => function ( array $m ) {
+                                       return '\\[' . ( strtolower( $m[1] ) != 
$m[1] ? 'Capital' : '' ) .
+                                                  ucfirst( $m[1] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Gamma: \GammaP@{a}{z}
+                               'search' =>
+                                       "~\\\\Gamma(?>[PQ])@?(" . $this->arg . 
"|" . $this->par . ")(" . $this->arg .
+                                       "|" . $this->par . ")~i",
+                               # Gamma (Incomplete):
+                               'replace' => function ( array $m ) {
+                                       return 'Gamma[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' . LaTeXTranslator::brackR( $m[4] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Gudermannian: \Gudermannian@{x}
+                               'search' => "~\\\\(arc)?Gudermannian@{0,2}(" . 
$this->arg . "|" . $this->par .
+                                                       ")~i",
+                               # Gudermannian: Gudermannian[z]
+                               'replace' => function ( array $m ) {
+                                       return ( strlen( $m[1] ) > 0 ? 
'Inverse' : '' ) . 'Gudermannian[' .
+                                                  LaTeXTranslator::brackR( 
$m[2] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Generalized Hermite: \GenHermiteH{n}@{x}
+                               'search' =>
+                                       "~\\\\GenHermiteH" . $this->par . 
"@{0,2}(" . $this->arg . "|" . $this->par .
+                                       ")~i",
+                               # Hermite: HermiteH[n,x]
+                               'replace' => function ( array $m ) {
+                                       return 'HermiteH[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' . LaTeXTranslator::brackR( $m[2] ) .
+                                                  ']';
+                               }
+                       ),
+                       array(
+                               # HurwitzZeta: \HurwitzZeta@{s}{a}
+                               'search' =>
+                                       "~\\\\HurwitzZeta@?(" . $this->arg . 
"|" . $this->par . ")(" . $this->arg .
+                                       "|" . $this->par . ")~i",
+                               # HurwitzZeta: HurwitzZeta[s,a]
+                               'replace' => function ( array $m ) {
+                                       return 'HurwitzZeta[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' . LaTeXTranslator::brackR( $m[4] ) .
+                                                  ']';
+                               }
+                       ),
+                       array(
+                               # Hypergeometric: \HypergeoF@{a}{b}{c}{d}
+                               'search' =>
+                                       "~\\\\HypergeoF(@{0,3})" . $this->par . 
$this->par . $this->par . $this->par .
+                                       "~i",
+                               # Hypergeometric: Hypergeometric2F1[a,b,c,d]
+                               'replace' => function ( array $m ) {
+                                       return 'Hypergeometric2F1[' . $m[2] . 
',' . $m[3] . ',' . $m[4] . ',' . $m[5] .
+                                                  ']';
+                               }
+                       ),
+                       array(
+                               # Hypergeometric (Generalized): 
\HyperpFq{p}{q}@{{\bf a}}{{\bf b}}{z}
+                               'search' =>
+                                       "~\\\\HyperpFq(" . $this->arg . "|" . 
$this->par . ")(" . $this->arg . "|" .
+                                       $this->par . ")@{0,3}(" . $this->arg . 
"|" . $this->par . ")(" . $this->arg .
+                                       "|" . $this->par . ")(" . $this->arg . 
"|" . $this->par . ")~i",
+                               # Hypergeometric (Generalized): 
HypergeometricPFQ[a,b,c]
+                               'replace' => function ( array $m ) {
+                                       return 'HypergeometricPFQ[' . $m[7] . 
',' . $m[10] . ',' .
+                                                  LaTeXTranslator::brackR( 
$m[13] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Incomplete Beta & Gamma: \IncBeta{x}@{a}{b}, 
\IncGamma@{a}{z}
+                               'search' => "~\\\\Inc(Beta|Gamma)" . $this->par 
. "?@{0,2}(" . $this->arg . "|" .
+                                                       $this->par . ")(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Incomplete Beta & Gamma: Beta[z,a,b], 
Gamma[a,z]
+                               'replace' => function ( array $m ) {
+                                       return
+                                               $m[1] . '[' . ( strlen( $m[2] ) 
> 0 ? LaTeXTranslator::brackR( $m[2] ) . ',' : '' ) .
+                                               LaTeXTranslator::brackR( $m[3] 
) . ',' . LaTeXTranslator::brackR( $m[6] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Inverse Error (including complementary): 
\inverfc@{x}
+                               'search' => "~\\\\inverf(c)?@{0,2}(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Inverse Error (including complementary): 
InverseErfc[x]
+                               'replace' => function ( array $m ) {
+                                       return 'InverseErf' . $m[1] . '[' . 
LaTeXTranslator::brackR( $m[2] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Imaginary Unit: \iunit
+                               'search' => "~\\\\iunit~i",
+                               # Imaginary Unit: I return 'I';}
+                               'replace' => function () {
+                                       return 'I';
+                               }
+                       ),
+                       array(
+                               # Jacobi Elliptics: \Jacobisd@{z}{k}
+                               'search' =>
+                                       
"~\\\\(arc)?Jacobi(Zeta|[a-z]{2})@{0,2}(" . $this->arg . "|" . $this->par .
+                                       ")(" . $this->arg . "|" . $this->par . 
")~i",
+                               # Jacobi Elliptics: JacobiSD[u,m]
+                               'replace' => function ( array $m ) {
+                                       return ( strlen( $m[1] ) > 0 ? 
'Inverse' : '' ) . 'Jacobi' .
+                                                  ( strlen( $m[2] ) == 2 ? 
strtoupper( $m[2] ) : 'Zeta' ) . '[' .
+                                                  LaTeXTranslator::brackR( 
$m[3] ) . ', Sqrt[' . LaTeXTranslator::brackR( $m[6] ) . ']]';
+                               }
+                       ),
+                       array(
+                               # Jacobi Polynomials: 
\JacobiP{\alpha}{\beta}{n}@{x}
+                               'search' =>
+                                       "~\\\\JacobiP" . $this->par . 
$this->par . $this->par . "@{0,2}(" . $this->arg .
+                                       "|" . $this->par . ")~i",
+                               # Jacobi Polynomial: JacobiP[n,a,b,x]
+                               'replace' => function ( array $m ) {
+                                       return
+                                               'JacobiP[' . 
LaTeXTranslator::brackR( $m[2] ) . ',' . LaTeXTranslator::brackR( $m[1] ) . ',' 
.
+                                               LaTeXTranslator::brackR( $m[3] 
) . ',' . LaTeXTranslator::brackR( $m[4] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Kelvin: \Kelvinber{\nu}@{x}
+                               'search' => "~\\\\Kelvin([bk]e[ri])(" . 
$this->par . ")@{0,2}(" . $this->arg . "|" .
+                                                       $this->par . ")?~i",
+                               # Kelvin: KelvinBer[n,z]
+                               'replace' => function ( array $m ) {
+                                       return 'Kelvin' . ucfirst( $m[1] ) . 
'[' . LaTeXTranslator::brackR( $m[2] ) .
+                                                  ( strlen( 
LaTeXTranslator::brackR( $m[4] ) ) > 0 ? ',' . LaTeXTranslator::brackR( $m[4] )
+                                                          : '' ) . ']';
+                               }
+                       ),
+                       array(
+                               # Klein Invariant: \ModularJ@{\tau}
+                               'search' => "~\\\\ModularJ" . $this->par . "~i",
+                               # Klein Invariant: KleinInvariantJ[\tau]
+                               'replace' => function ( array $m ) {
+                                       return 'KleinInvariantJ[' . 
LaTeXTranslator::brackR( $m[1] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Kronecker: \Kronecker{j}{k}
+                               'search' => "~\\\\Kronecker" . $this->par . 
$this->par . "~i",
+                               # Kronecker: Kronecker[j,k]
+                               'replace' => function ( array $m ) {
+                                       return
+                                               'KroneckerDelta[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' . LaTeXTranslator::brackR( $m[2] ) .
+                                               ']';
+                               }
+                       ),
+                       array(
+                               # LaguerreL[\a]{n}@{x}
+                               'search' =>
+                                       "~\\\\LaguerreL(\\[.*\\])?" . 
$this->par . "@?(" . $this->arg . "|" . $this->par .
+                                       ")~i",
+                               # LaguerreL: LaguerreL[n,a,x]
+                               'replace' => function ( array $m ) {
+                                       return 'LaguerreL[' . 
LaTeXTranslator::brackR( $m[2] ) . ',' .
+                                                  ( strlen( 
LaTeXTranslator::brackR( $m[1] ) ) > 0 ? LaTeXTranslator::brackR( $m[1] ) . ','
+                                                          : '' ) . 
LaTeXTranslator::brackR( $m[3] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Legendre/Ferrers: \LegendreP[\mu]{\nu}@{x} | 
\FerrersP[\mu]{\nu}@{x}
+                               'search' =>
+                                       
"~\\\\(?>Legendre|Ferrers)([PQ]|Poly)(\\[(?>[^{}]|(?-1))*\\])?" . $this->par .
+                                       "@?(" . $this->arg . "|" . $this->par . 
")?~i",
+                               # Legendre/Ferrers: LegendreP[\nu,x] | 
LegendreP[\nu,\mu,x]
+                               'replace' => function ( array $m ) {
+                                       return 'Legendre' . $m[1] . '[' . 
LaTeXTranslator::brackR( $m[3] ) . ',' .
+                                                  ( strlen( 
LaTeXTranslator::brackR( $m[2] ) ) > 0 ? LaTeXTranslator::brackR( $m[2] ) . ','
+                                                          : '' ) . 
LaTeXTranslator::brackR( $m[5] ) . ']';
+                               }
+                       ),
+                       array(
+                               # LerchPhi: \LerchPhi@{z}{s}{a}
+                               'search' =>
+                                       "~\\\\LerchPhi@{0,2}(" . $this->arg . 
"|" . $this->par . ")(" . $this->arg .
+                                       "|" . $this->par . ")(" . $this->arg . 
"|" . $this->par . ")~i",
+                               # LerchPhi: LerchPhi[z,s,a]
+                               'replace' => function ( array $m ) {
+                                       return
+                                               'LerchPhi[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' . LaTeXTranslator::brackR( $m[4] ) . ',' 
.
+                                               LaTeXTranslator::brackR( $m[7] 
) . ']';
+                               }
+                       ),
+                       array(
+                               # Log Integral: \LogInt@{x}
+                               'search' => "~\\\\LogInt@{0,2}(" . $this->arg . 
"|" . $this->par . ")~i",
+                               # Log Integral: LogIntegral[x]
+                               'replace' => function ( array $m ) {
+                                       return 'LogIntegral[' . 
LaTeXTranslator::brackR( $m[1] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Mittag-Leffler: \MittagLeffler{a}{b}@{z}
+                               'search' =>
+                                       "~\\\\MittagLeffler" . $this->par . 
$this->par . "@{0,2}(" . $this->arg . "|" .
+                                       $this->par . ")~i",
+                               # Mittag-Leffler: MittagLefflerE[\alpha,\beta,z]
+                               'replace' => function ( array $m ) {
+                                       return
+                                               'MittagLefflerE[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' . LaTeXTranslator::brackR( $m[2] ) .
+                                               ',' . LaTeXTranslator::brackR( 
$m[3] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Modulus: n \mod m
+                               'search' =>
+                                       "~(" . $this->arg . "|" . $this->par . 
")\\\\mod@{0,2}(" . $this->arg . "|" .
+                                       $this->par . ")~i",
+                               # Modulus: Mod[m,n]
+                               'replace' => function ( array $m ) {
+                                       return 'Mod[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' . LaTeXTranslator::brackR( $m[4] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Permutations: \Permutations{n}
+                               'search' => "~\\\\Permutations@{0,2}(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Permutations: Permutations[n]
+                               'replace' => function ( array $m ) {
+                                       return 'Permutations[' . 
LaTeXTranslator::brackR( $m[1] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Pochhammer: \pochammer{a}{n}
+                               'search' => "~\\\\pochhammer@{0,2}" . 
$this->par . $this->par . "~i",
+                               # Pochhammer: Pochhammer[a,n]
+                               'replace' => function ( array $m ) {
+                                       return 'Pochhammer[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' . LaTeXTranslator::brackR( $m[2] ) .
+                                                  ']';
+                               }
+                       ),
+                       array(
+                               # PolyGamma: \polygamma{n}@{z}
+                               'search' =>
+                                       "~\\\\Polygamma" . $this->par . 
"@{0,2}(" . $this->arg . "|" . $this->par .
+                                       ")~i",
+                               # PolyGamma: PolyGamma[n,z]
+                               'replace' => function ( array $m ) {
+                                       return 'PolyLog[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' . LaTeXTranslator::brackR( $m[2] ) . ']';
+                               }
+                       ),
+                       array(
+                               # PolyLog: \Polylogarithms{x}@{z}
+                               'search' =>
+                                       "~\\\\Polylogarithm" . $this->par . 
"@{0,2}(" . $this->arg . "|" . $this->par .
+                                       ")~i",
+                               # PolyLog: PolyLog[x,z]
+                               'replace' => function ( array $m ) {
+                                       return 'PolyLog[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' . LaTeXTranslator::brackR( $m[2] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Q Factorial: \qFactorial{a}{q}{n}
+                               'search' => "~\\\\qFactorial@{0,2}" . 
$this->par . $this->par . $this->par . "~i",
+                               # Q Factorial: QFactorial[a,q,n]
+                               'replace' => function ( array $m ) {
+                                       return 'QFactorial[' . 
LaTeXTranslator::brackR( $m[2] ) . ',' . LaTeXTranslator::brackR( $m[3] ) .
+                                                  ']';
+                               }
+                       ),
+                       array(
+                               # Q Gamma: \qGamma{q}@{z}
+                               'search' => "~\\\\qGamma" . $this->par . 
"@{0,2}(" . $this->arg . "|" . $this->par .
+                                                       ")~i",
+                               # Q Gamma: QGamma[z,q]
+                               'replace' => function ( array $m ) {
+                                       return 'QGamma[' . 
LaTeXTranslator::brackR( $m[2] ) . ',' . LaTeXTranslator::brackR( $m[1] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Ramanujan Tau: \RamanujanTau@{k}
+                               'search' => "~\\\\RamanujanTau@{0,2}(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Ramanujan Tau: RamanujanTau[k]
+                               'replace' => function ( array $m ) {
+                                       return 'RamanujanTau[' . 
LaTeXTranslator::brackR( $m[1] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Real Part: \realpart{z}
+                               'search' => "~\\\\realpart@{0,2}" . $this->par 
. "~i",
+                               # Real Part: Re[z]
+                               'replace' => function ( array $m ) { return 
'Re[' . LaTeXTranslator::brackR( $m[1] ) . ']'; }
+                       ),
+                       array(
+                               # Riemann: \RiemannXi@{s}
+                               'search' => "~\\\\Riemann(Xi)@{0,2}(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Riemann: RiemannXi[s]
+                               'replace' => function ( array $m ) {
+                                       return 'Riemann' . $m[1] . '[' . 
LaTeXTranslator::brackR( $m[2] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Scorer: \ScorerHi@{z}
+                               'search' => "~\\\\Scorer([G|H]i)@{0,2}(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Scorer: ScorerHi[z]
+                               'replace' => function ( array $m ) {
+                                       return 'Scorer' . $m[1] . '[' . 
LaTeXTranslator::brackR( $m[2] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Sign: \sign@{x}
+                               'search' => "~\\\\sign@{0,2}(" . $this->arg . 
"|" . $this->par . ")~i",
+                               # Sign: Sign[z]
+                               'replace' => function ( array $m ) {
+                                       return 'Sign[' . 
LaTeXTranslator::brackR( $m[1] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Sin Integral: \SinInt@{x}
+                               'search' => "~\\\\Sin(h?)Int@{0,2}(" . 
$this->arg . "|" . $this->par . ")~i",
+                               # Sin Integral: SinInt[z]
+                               'replace' => function ( array $m ) {
+                                       return 'Sin' . $m[1] . 'Integral[' . 
LaTeXTranslator::brackR( $m[2] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Spherical BesselJ/Y | HankelH1/H2: 
\SphBesselJ{n}@{z}
+                               'search' =>
+                                       "~\\\\Sph(Bessel|Hankel)(J|Y|Hii?)" . 
$this->par . "@{0,2}(" . $this->arg .
+                                       "|" . $this->par . ")~i",
+                               # Spherical BesselJ/Y | HankelH1/H2: 
SphericalBesselJ[n,z]
+                               'replace' => function ( array $m ) {
+                                       return 'Spherical' . $m[1] . '' . ( 
substr( $m[2], 0, 2 ) !== 'Hi'
+                                               ? $m[2] : 'H' . ( strlen( $m[2] 
) - 1 ) ) . '[' . LaTeXTranslator::brackR( $m[3] ) .
+                                                  ',' . 
LaTeXTranslator::brackR( $m[4] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Spherical Harmonic: 
\SphericalHarmonicY{l}{m}@{\theta}{\phi}
+                               'search' =>
+                                       "~\\\\SphericalHarmonicY" . $this->par 
. $this->par . "@?(" . $this->arg . "|" .
+                                       $this->par . ")?(" . $this->arg . "|" . 
$this->par . ")?~i",
+                               # Spherical Harmonic: 
SphericalHarmonicY[l,m,\theta,\phi]
+                               'replace' => function ( array $m ) {
+                                       return 'SphericalHarmonicY[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' .
+                                                  LaTeXTranslator::brackR( 
$m[2] ) . ',' . LaTeXTranslator::brackR( $m[3] ) . ',' .
+                                                  LaTeXTranslator::brackR( 
$m[6] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Spheroidal Eigenvalue: 
\SpheroidalEigenvalueLambda{m}{n}@{\gamma}
+                               'search' => "~\\\\SpheroidalEigenvalueLambda" . 
$this->par . $this->par . "@?(" .
+                                                       $this->arg . "|" . 
$this->par . ")?~i",
+                               # Spheroidal Eigenvalue: 
SpheroidalEigenvalue[n,m,\gamma]
+                               'replace' => function ( array $m ) {
+                                       return 'SpheroidalEigenvalue[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' .
+                                                  LaTeXTranslator::brackR( 
$m[2] ) . ',' . LaTeXTranslator::brackR( $m[3] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Spheroidal Ps: 
\SpheroidalPs{m}{n}@{z}{\gamma^2}
+                               'search' =>
+                                       "~\\\\Spheroidal(P|Q)s" . $this->par . 
$this->par . "@?(" . $this->arg . "|" .
+                                       $this->par . ")?(" . $this->arg . "|" . 
$this->par . ")?~i",
+                               # Spheroidal Ps: SpheroidalPs[n,m,\gamma,z]
+                               'replace' => function ( array $m ) {
+                                       return 'Spheroidal' . $m[1] . 'S[' . 
LaTeXTranslator::brackR( $m[2] ) . ',' .
+                                                  LaTeXTranslator::brackR( 
$m[3] ) . ',Sqrt[' . LaTeXTranslator::brackR( $m[7] ) . '],' .
+                                                  LaTeXTranslator::brackR( 
$m[4] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Sqrt: \sqrt@{x}
+                               'search' => "~\\\\sqrt@{0,2}(" . $this->arg . 
"|" . $this->par . ")~i",
+                               # Sqrt: Sqrt[x]
+                               'replace' => function ( array $m ) {
+                                       return 'Sqrt[' . 
LaTeXTranslator::brackR( $m[1] ) . ']';
+                               }
+                       ),
+                       array(
+                               # StruveH: \StruveH{\nu}@{z}
+                               'search' =>
+                                       "~\\\\Struve(H|L)" . $this->par . 
"@{0,2}(" . $this->arg . "|" . $this->par .
+                                       ")~i",
+                               # StruveH: StruveH[n,z]
+                               'replace' => function ( array $m ) {
+                                       return 'Struve' . $m[1] . '[' . 
LaTeXTranslator::brackR( $m[2] ) . ',' .
+                                                  LaTeXTranslator::brackR( 
$m[3] ) . ']';
+                               }
+                       ),
+                       array(
+                               # WeberE: \WeberE{\nu}@{z}
+                               'search' => "~\\\\WeberE" . $this->par . 
"@{0,2}(" . $this->arg . "|" . $this->par .
+                                                       ")~i",
+                               # WeberE: WeberE[\nu,z]
+                               'replace' => function ( array $m ) {
+                                       return 'WeberE[' . 
LaTeXTranslator::brackR( $m[1] ) . ',' . LaTeXTranslator::brackR( $m[2] ) . ']';
+                               }
+                       ),
+                       array(
+                               # Whittaker: \WhittakerM{\kappa}{\mu}@{z}
+                               'search' =>
+                                       "~\\\\Whit(M|W)" . $this->par . 
$this->par . "@{0,2}(" . $this->arg . "|" .
+                                       $this->par . ")~i",
+                               # Whittaker: WhittakerW[k,m,z]
+                               'replace' => function ( array $m ) {
+                                       return 'Whittaker' . $m[1] . '[' . 
LaTeXTranslator::brackR( $m[2] ) . ',' .
+                                                  LaTeXTranslator::brackR( 
$m[3] ) . ',' . LaTeXTranslator::brackR( $m[4] ) . ']';
+                               }
+                       )
+               );
+       }
+       /**
+        * @var string contains data in Wiki html input form
+        */
+
+       /**
+        * Returns LaTeX arguments without curly brackets
+        * @param $arg
+        * @return string
+        */
+       public static function brackR( $arg ) {
+               $arg = trim( $arg, " " );
+               if ( substr( $arg, 0,1) == "{" && substr( $arg,  -1) == "}" ) {
+                       $arg = substr( $arg, 1, strlen( $arg ) - 2 );
+               }
+               return $arg;
+       }
+
+       /**
+        * Processes the submitted Form input
+        * @param string $data
+        * @return string
+        */
+       public function processInput( $data ) {
+               foreach ( $this->replacements as $set ) {
+                       $data =
+                               preg_replace_callback( $set['search'],
+                                       // select the correct replacement 
callback depending on $allowimgcode
+                                       $set['replace'], $data );
+               }
+               return $data;
+       }
+}
diff --git a/includes/special/SpecialLaTeXTranslator.php 
b/includes/special/SpecialLaTeXTranslator.php
new file mode 100644
index 0000000..5e62098
--- /dev/null
+++ b/includes/special/SpecialLaTeXTranslator.php
@@ -0,0 +1,51 @@
+<?php
+
+class SpecialLaTeXTranslator extends SpecialPage {
+       /**
+        * @var LaTeXTranslator
+        */
+       private $translator;
+       function __construct() {
+               parent::__construct( 'LaTeXTranslator' );
+               $this->translator = new LaTeXTranslator();
+       }
+
+       /**
+        * Returns corresponding Mathematica translations of LaTeX functions
+        * @param $par
+        */
+       function execute( $par ) {
+               $this->setHeaders();
+               $output = $this->getOutput();
+               $output->addWikiMsg( 'math-tex2nb-intro' );
+               $formDescriptor = array(
+                       'input' => array(
+                               'label-message' => 'math-tex2nb-input',
+                               'class' => 'HTMLTextAreaField',
+                               'default' => '\log x'
+                       )
+               );
+               $htmlForm = new HTMLForm( $formDescriptor, $this->getContext() 
);
+               $htmlForm->setSubmitText( 'Translate' );
+               $htmlForm->setSubmitCallback( array( $this, 'processInput' ) );
+               $htmlForm->setHeaderText( '<h2>' . wfMessage( 
'math-tex2nb-header' )->toString() . '</h2>' );
+               $htmlForm->show();
+       }
+
+       /**
+        * Processes the submitted Form input
+        * @param array $formData
+        * @return bool
+        */
+       public function processInput( $formData ) {
+               $data = $formData['input'];
+
+               $translated = $this->translator->processInput( $data );
+
+               $output = $this->getOutput();
+               $output->addWikiMsg( 'math-tex2nb-latex' );
+               $output->addWikiText( "<syntaxhighlight 
lang='latex'>$data</syntaxhighlight>" );
+               $output->addWikiMsg( 'math-tex2nb-mathematica' );
+               $output->addWikiText( "<syntaxhighlight 
lang='text'>$translated</syntaxhighlight>" );
+       }
+}
diff --git a/tests/LaTeX2MathematicaTest.php b/tests/LaTeX2MathematicaTest.php
new file mode 100644
index 0000000..5db3244
--- /dev/null
+++ b/tests/LaTeX2MathematicaTest.php
@@ -0,0 +1,41 @@
+<?php
+class LaTeX2MathematicaTest extends MediaWikiTestCase {
+       /**
+        * @var LaTeXTranslator
+        */
+       private $translator;
+
+       /**
+        * Sets up the fixture, for example, opens a network connection.
+        * This method is called before a test is executed.
+        */
+       protected function setUp() {
+               $this->translator = new LaTeXTranslator();
+               parent::setUp();
+       }
+       /**
+        * Loops over all test cases provided by the provider function.
+        * Compares each the rendering result of each input with the expected 
output.
+        * @dataProvider provideCoverage
+        */
+       public function testCoverage( $input, $output ) {
+               $this->assertEquals(
+                       $this->normalize( $output ),
+                       $this->normalize( $this->translator->processInput( 
$input ) ),
+                       "Failed to render $input"
+               );
+       }
+
+       /**
+        * Gets the test-data from the json file
+        * @return array($input, $output) where $input is the input LaTeX 
string and $output is the
+        * rendered Mathematica string
+        */
+       public function provideCoverage() {
+               return json_decode( file_get_contents( __DIR__ . '/tex2nb.json' 
) );
+       }
+
+       private function normalize( $input ) {
+               return $input;
+       }
+}
diff --git a/tests/tex2nb.json b/tests/tex2nb.json
new file mode 100644
index 0000000..4604f90
--- /dev/null
+++ b/tests/tex2nb.json
@@ -0,0 +1,240 @@
+[
+       [
+         "\\Alpha = 0.5",
+          "\\[CapitalAlpha] = 0.5"
+       ],[
+         "\\Beta = 0.4",
+          "\\[CapitalBeta] = 0.4"
+       ],[
+         "\\Gamma = 0.3",
+          "\\[CapitalGamma] = 0.3"
+       ],[
+         "\\Delta = 0.2",
+          "\\[CapitalDelta] = 0.2"
+       ],[
+         "\\Epsilon = 0.1",
+          "\\[CapitalEpsilon] = 0.1"
+       ],[
+         "\\lambda = 6",
+          "\\[Lambda] = 6"
+       ],[
+         "\\mu = 5",
+          "\\[Mu] = 5"
+       ],[
+         "\\nu = 4",
+          "\\[Nu] = 4"
+       ],[
+         "\\rho = 3",
+          "\\[Rho] = 3"
+       ],[
+         "\\sigma = 2",
+          "\\[Sigma] = 2"
+       ],[
+         "\\phi = 1",
+          "\\[Phi] = 1"
+       ],[
+         "\\nu = 5",
+          "\\[Nu] = 5"
+       ],[
+         "\\sin@@\\sigma",
+          "Sin[\\[Sigma]]"
+       ],[
+         "\\AiryAi@{\\phi}",
+          "AiryAi[\\[Phi]]"
+       ],[
+         "\\AiryBi{\\phi}",
+          "AiryBi[\\[Phi]]"
+       ]
+,[       "\\AiryModulusM@{\\nu}",
+          "Sqrt[AiryAi[\\[Nu]]^2+AiryBi[\\[Nu]]^2]"
+       ],[
+         "\\AGM@{\\phi}{\\sigma}",
+          "ArithmeticGeometricMean[\\[Phi],\\[Sigma]]"
+       ],[
+         "\\AngerJ{\\phi}@{\\sigma}",
+          "AngerJ[\\[Phi],\\[Sigma]]"
+       ],[
+         "\\AppellFi@{\\phi}{\\sigma}{\\rho}{\\nu}{\\mu}{\\lambda}",
+          "AppellF1[\\[Phi],\\[Sigma],\\[Rho],\\[Nu],\\[Mu],\\[Lambda]]"
+       ],[
+         "\\BarnesGamma@{\\sigma}",
+          "BarnesG[\\[Sigma]]"
+       ],[
+         "\\BesselJ{\\Alpha}@{\\Alpha}",
+          "BesselJ[\\[CapitalAlpha],\\[CapitalAlpha]]"
+       ],[
+         "\\binom{\\sigma}{\\phi}",
+          "Binomial[\\[Phi],\\[Sigma]]"
+       ],[
+         "\\CatalanNumber@{\\Epsilon}",
+          "CatalanNumber[\\[CapitalEpsilon]]"
+       ],[
+         "\\ceiling{\\sigma}",
+          "Ceiling[\\[Sigma]]"
+       ],[
+         "\\ChebyT{\\Alpha}@{\\Alpha}",
+          "ChebyshevT[\\[CapitalAlpha],\\[CapitalAlpha]]"
+       ],[
+         "\\conj{3 + 7 I}",
+          "Conjugate[3 + 7 I]"
+       ],[
+         "\\coshint@\\phi",
+          "CoshIntegral[\\[Phi]]"
+       ],[
+         "\\Cylinder{\\Epsilon}{\\phi}",
+          "ParabolicCylinderD[\\[CapitalEpsilon],\\[Phi]]"
+       ],[
+         "\\DawsonsInt@{\\phi I}",
+          "DawsonF[\\[Phi] I]"
+       ],[
+         "\\DedekindModularEta@{\\phi + I}",
+          "DedekindEta[\\[Phi] + I]"
+       ],[
+         "\\deriv{\\sigma x}{x}",
+          "D[\\[Sigma] x,x]"
+       ],[
+         "\\det{\\phi}",
+          "Det[{\\[Phi]}]"
+       ],[
+         "\\CompEllIntK@@{\\Alpha}",
+          "EllipticK[Sqrt[\\[CapitalAlpha]]]"
+       ],[
+         "\\EllIntK@{\\Delta\\phi}",
+          "EllipticK[Sqrt[\\[CapitalDelta]\\[Phi]]]"
+       ],[
+         "\\EulerBeta{\\phi}{\\sigma}",
+          "Beta[\\[Phi],\\[Sigma]]"
+       ],[
+         "\\exp@{\\Delta x}",
+          "Exp[\\[CapitalDelta] x]"
+       ],[
+         "\\ExpInti@{\\Epsilon}",
+          "Exp[I]nti@{\\[CapitalEpsilon]}"
+       ],[
+         "\\frac{\\phi}\\sigma",
+          "(\\[Phi])/\\[Sigma]"
+       ],[
+         "\\FresnelSin@{\\Alpha}",
+          "FresnelS[\\[CapitalAlpha]]"
+       ],[
+         "\\floor{\\phi*\\sigma}",
+          "Floor[\\[Phi]*\\[Sigma]]"
+       ],[
+         "\\GenHermiteH{\\phi}@{\\sigma}",
+          "HermiteH[\\[Phi],\\[Sigma]]"
+       ],[
+         "\\Gudermannian{\\cos@\\phi}",
+          "Gudermannian[Cos[\\[Phi]]]"
+       ],[
+         "\\HurwitzZeta@{\\Gudermannian{\\sin@\\phi}}{\\Alpha}",
+          "HurwitzZeta[Gudermannian[Sin[\\[Phi]]],\\[CapitalAlpha]]"
+       ],[
+         "\\HypergeoF@{\\Alpha}{\\Beta}{\\Gamma}{\\Delta}",
+          
"Hypergeometric2F1[{\\[CapitalAlpha]},{\\[CapitalBeta]},{\\[CapitalGamma]},{\\[CapitalDelta]}]"
+       ],[
+         "\\HyperpFq{\\phi}{\\sigma}@{\\phi}{\\phi,\\sigma}{\\rho}",
+          "HypergeometricPFQ[{\\[Phi]},{\\[Phi],\\[Sigma]},\\[Rho]]"
+       ],[
+         "\\IncBeta{\\rho}@{\\phi}{\\sigma}",
+          "Beta[\\[Rho],\\[Phi],\\[Sigma]]"
+       ],[
+         "\\inverfc@\\phi",
+          "InverseErfc[\\[Phi]]"
+       ],[
+         "\\Jacobisd@{\\nu}{\\sigma}",
+          "JacobiSD[\\[Nu], Sqrt[\\[Sigma]]]"
+       ],[
+         "\\JacobiP{\\phi}{\\sigma}{\\rho}@{\\nu}",
+          "JacobiP[\\[Sigma],\\[Phi],\\[Rho],\\[Nu]]"
+       ],[
+         "\\JacobiZeta@{\\Alpha}{\\Alpha}",
+          "JacobiZeta[\\[CapitalAlpha], Sqrt[\\[CapitalAlpha]]]"
+       ],[
+         "\\Kelvinber{\\nu}@{\\Gamma}",
+          "KelvinBer[\\[Nu],\\[CapitalGamma]]"
+       ],[
+         "\\Kronecker{\\Alpha}{\\Alpha}",
+          "KroneckerDelta[\\[CapitalAlpha],\\[CapitalAlpha]]"
+       ],[
+         "\\LaguerreL[\\Alpha]{\\nu}@{x}",
+          "LaguerreL[\\[Nu],[\\[CapitalAlpha]],x]"
+       ],[
+         "\\LegendreP{\\Alpha}@\\phi",
+          "LegendreP[\\[CapitalAlpha],\\[Phi]]"
+       ],[
+         "\\LogInt@{\\Alpha}",
+          "Log[I]nt@{\\[CapitalAlpha]}"
+       ],[
+         "\\LerchPhi@{\\phi}{\\sigma}{\\rho}",
+          "LerchPhi[\\[Phi],\\[Sigma],\\[Rho]]"
+       ],[
+         "\\MittagLeffler{\\phi}{\\sigma}{\\rho}",
+          "MittagLefflerE[\\[Phi],\\[Sigma],\\[Rho]]"
+       ],[
+         "5\\mod2",
+          "Mod[5,2]"
+       ],[
+         "\\ModularJ{\\phi}",
+          "KleinInvariantJ[\\[Phi]]"
+       ],[
+         "\\pochhammer{\\phi}{\\sigma}",
+          "Pochhammer[\\[Phi],\\[Sigma]]"
+       ],[
+         "\\polygamma{\\Alpha}@{\\Beta}",
+          "PolyLog[\\[CapitalAlpha],\\[CapitalBeta]]"
+       ],[
+         "\\Polylogarithm{\\Alpha}@{\\Alpha}",
+          "PolyLog[\\[CapitalAlpha],\\[CapitalAlpha]]"
+       ],[
+         "\\qFactorial{\\lambda}{\\mu}{\\nu}",
+          "QFactorial[\\[Mu],\\[Nu]]"
+       ],[
+         "\\qGamma{\\Alpha}@{\\Alpha}",
+          "QGamma[\\[CapitalAlpha],\\[CapitalAlpha]]"
+       ],[
+         "\\RamanujanTau@{\\rho}",
+          "RamanujanTau[\\[Rho]]"
+       ],[
+         "\\realpart{\\rho I+\\nu}",
+          "Re[\\[Rho] I+\\[Nu]]"
+       ],[
+         "\\RiemannXi@{\\Alpha}",
+          "RiemannXi[\\[CapitalAlpha]]"
+       ],[
+         "\\ScorerHi@{\\Alpha}",
+          "ScorerHi[\\[CapitalAlpha]]"
+       ],[
+         "\\sign@{-\\Alpha}",
+          "Sign[-\\[CapitalAlpha]]"
+       ],[
+         "\\SinInt@{\\Alpha}",
+          "SinIntegral[\\[CapitalAlpha]]"
+       ],[
+         "\\SphBesselY{\\Alpha}@{\\phi}",
+          "SphericalBesselY[\\[CapitalAlpha],\\[Phi]]"
+       ],[
+         "\\SphHankelHii{\\Alpha}@{\\Beta}",
+          "SphericalHankelH2[\\[CapitalAlpha],\\[CapitalBeta]]"
+       ],[
+         "\\SphericalHarmonicY{\\Epsilon}{\\Delta}@{\\Gamma}{\\Beta}",
+          
"SphericalHarmonicY[\\[CapitalEpsilon],\\[CapitalDelta],\\[CapitalGamma],\\[CapitalBeta]]"
+       ],[
+         "\\SpheroidalEigenvalueLambda{\\Epsilon}{\\Delta}@{\\Gamma}",
+          
"SpheroidalEigenvalue[\\[CapitalEpsilon],\\[CapitalDelta],\\[CapitalGamma]]"
+       ],[
+         "\\SpheroidalPs{\\Epsilon}{\\Delta}@{\\Gamma}{\\Beta}",
+          
"SpheroidalPS[\\[CapitalEpsilon],\\[CapitalDelta],Sqrt[\\[CapitalBeta]],\\[CapitalGamma]]"
+       ],[
+         "\\sqrt\\sigma",
+          "Sqrt[\\[Sigma]]"
+       ],[
+         "\\StruveL{\\Epsilon}@{\\Delta}",
+          "StruveL[\\[CapitalEpsilon],\\[CapitalDelta]]"
+       ],[
+         "\\WeberE{\\Epsilon}{\\Delta}",
+          "WeberE[\\[CapitalEpsilon],\\[CapitalDelta]]"
+       ],[
+         "\\WhitW{\\Epsilon}{\\Delta}@{\\Gamma}",
+          "WhittakerW[\\[CapitalEpsilon],\\[CapitalDelta],\\[CapitalGamma]]"
+       ]
+  ]
\ No newline at end of file

-- 
To view, visit https://gerrit.wikimedia.org/r/203954
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ie5ef7ee76c9a9daa1b3c42a007914f8f1b9a6d2e
Gerrit-PatchSet: 16
Gerrit-Project: mediawiki/extensions/MathSearch
Gerrit-Branch: master
Gerrit-Owner: Sharmaans <[email protected]>
Gerrit-Reviewer: Hcohl <[email protected]>
Gerrit-Reviewer: Physikerwelt <[email protected]>
Gerrit-Reviewer: Raimond Spekking <[email protected]>
Gerrit-Reviewer: Sharmaans <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to