Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 111 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 1 |
JsonToMathML | |
0.00% |
0 / 108 |
|
0.00% |
0 / 7 |
930 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
readJsonAndGenerateMML | |
0.00% |
0 / 35 |
|
0.00% |
0 / 1 |
156 | |||
formatInput | |
0.00% |
0 / 43 |
|
0.00% |
0 / 1 |
156 | |||
getJSON | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
writeToFile | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
fetchMathML | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | /** |
3 | * This program is free software; you can redistribute it and/or modify |
4 | * it under the terms of the GNU General Public License as published by |
5 | * the Free Software Foundation; either version 2 of the License, or |
6 | * (at your option) any later version. |
7 | * |
8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | * GNU General Public License for more details. |
12 | * |
13 | * You should have received a copy of the GNU General Public License along |
14 | * with this program; if not, write to the Free Software Foundation, Inc., |
15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
16 | * http://www.gnu.org/copyleft/gpl.html |
17 | * |
18 | * @ingroup Maintenance |
19 | */ |
20 | |
21 | use MediaWiki\Extension\Math\MathRenderer; |
22 | use MediaWiki\Maintenance\Maintenance; |
23 | |
24 | require_once __DIR__ . '/../../../maintenance/Maintenance.php'; |
25 | |
26 | /** |
27 | * From a specified json file with (La)TeX formula as input, |
28 | * create a json file with the Tex and corresponding MathML. |
29 | * This is mostly used for generating Test-Content for the MathML features of WikiTexVC. |
30 | * |
31 | * The script fetches: |
32 | * - Mathoid MathML (mode: 'mathml') |
33 | * - LaTeXML MathML (mode: 'latexml') |
34 | * |
35 | * @author Johannes Stegmüller |
36 | */ |
37 | class JsonToMathML extends Maintenance { |
38 | /** @var string */ |
39 | private $inputPath = ""; |
40 | |
41 | /** @var string */ |
42 | private $outputPath = ""; |
43 | /** @var int */ |
44 | private $inputFormat = 0; |
45 | |
46 | public function __construct() { |
47 | parent::__construct(); |
48 | $this->addDescription( 'From a JSON file containing (La)TeX math inputs, create a JSON file with LaTeX and ' . |
49 | 'corresponding MathML.' ); |
50 | $this->addArg( 'input-path', "Path (with filename) of the json file read by this script.", |
51 | true ); |
52 | $this->addArg( 'output-path', "Path (with filename) of the output json file created by this script.", |
53 | true ); |
54 | $this->addOption( 'inputformat', 'Custom parsing how to format the input-json (see formatInput function)', |
55 | false, true, 'i' ); |
56 | $this->addOption( 'chem-fallback', 'If the json read does not define input-type (tex or chem), check ' . |
57 | 'expressions as Tex and then as chem', false, true, 'c' ); |
58 | $this->requireExtension( 'Math' ); |
59 | } |
60 | |
61 | public function execute() { |
62 | $this->inputFormat = $this->getOption( "inputformat", 0 ); |
63 | $this->inputPath = $this->getArg( 0 ); |
64 | $this->outputPath = $this->getArg( 1 ); |
65 | $this->readJsonAndGenerateMML(); |
66 | } |
67 | |
68 | public function readJsonAndGenerateMML() { |
69 | $inputTex = $this->getJSON( $this->inputPath ); |
70 | if ( $inputTex == null ) { |
71 | throw new InvalidArgumentException( "Provide a json file as input which has content" ); |
72 | } |
73 | $inputTexF = $this->formatInput( $inputTex ); |
74 | $allEntries = []; |
75 | |
76 | foreach ( $inputTexF as $entry ) { |
77 | try { |
78 | $mmlMathoid = $this->fetchMathML( $entry['tex'], $entry['type'], 'mathml' ); |
79 | if ( ( $this->getOption( "chem-fallback", 0 ) && !$mmlMathoid ) || $mmlMathoid == "" ) { |
80 | $mmlMathoid = $this->fetchMathML( $entry['tex'], "chem", 'mathml' ); |
81 | if ( $mmlMathoid && $mmlMathoid != "" ) { |
82 | $entry['type'] = "chem"; |
83 | } |
84 | } |
85 | $mmlLaTeXML = $this->fetchMathML( $entry['tex'], $entry['type'], 'latexml' ); |
86 | $entryToAdd = [ |
87 | "tex" => $entry['tex'], |
88 | "type" => $entry['type'], |
89 | "mmlMathoid" => $mmlMathoid, |
90 | "mmlLaTeXML" => $mmlLaTeXML |
91 | ]; |
92 | |
93 | if ( array_key_exists( "texNew", $entry ) ) { |
94 | $entryToAdd["texNew"] = $entry["texNew"]; |
95 | } |
96 | if ( array_key_exists( "typeC", $entry ) ) { |
97 | $entryToAdd["typeC"] = $entry["typeC"]; |
98 | } |
99 | if ( array_key_exists( "description", $entry ) ) { |
100 | $entryToAdd["description"] = $entry["description"]; |
101 | } |
102 | |
103 | $allEntries[] = $entryToAdd; |
104 | } catch ( Exception $e ) { |
105 | $allEntries[] = [ |
106 | "tex" => $entry['tex'], |
107 | "type" => $entry['type'], |
108 | "mmlMathoid" => "skipped (Exception)", |
109 | "mmlLaTeXML" => "skipped (Exception)", |
110 | "skipped" => true, |
111 | ]; |
112 | $this->output( "Exception occurred during rendering:" . $entry['tex'] . " render:" . $e . "\n" ); |
113 | } |
114 | } |
115 | |
116 | $this->writeToFile( $this->outputPath, $allEntries ); |
117 | } |
118 | |
119 | /** |
120 | * Creates a uniform array of data from files for more convenient parsing. |
121 | * @param array $fileData input read from json, format can differ |
122 | * @return array uniform array |
123 | */ |
124 | private function formatInput( $fileData ) { |
125 | $inputF = []; |
126 | switch ( $this->inputFormat ) { |
127 | case 0: |
128 | // Example file ParserTest135.json |
129 | foreach ( $fileData as $entry ) { |
130 | $inputF[] = [ |
131 | "tex" => $entry['input'], |
132 | "type" => "tex", |
133 | ]; |
134 | } |
135 | break; |
136 | case 1: |
137 | // Example file TexUtilMMLLookup.json |
138 | foreach ( $fileData as $tex => $mml ) { |
139 | $inputF[] = [ |
140 | "tex" => $tex, |
141 | "type" => "tex", |
142 | ]; |
143 | } |
144 | break; |
145 | case 2: |
146 | // Example file ExportedTexUtilKeys.json |
147 | foreach ( $fileData as $tex => $type ) { |
148 | $inputF[] = [ |
149 | "tex" => $tex, |
150 | "type" => $type, |
151 | ]; |
152 | } |
153 | break; |
154 | case 3: |
155 | // Example file Mhchemv4tex.json |
156 | foreach ( $fileData as $group => $cases ) { |
157 | foreach ( $cases as $case ) { |
158 | $inputF[] = [ |
159 | "description" => $group, |
160 | "tex" => $case["tex"], |
161 | "texNew" => $case["texNew"], |
162 | "type" => "chem", |
163 | "typeC" => $case["type"] |
164 | ]; |
165 | } |
166 | } |
167 | break; |
168 | case 4: |
169 | // Example file ExamplesNewCommandsMhchem.json |
170 | foreach ( $fileData as $entry ) { |
171 | $inputF[] = [ |
172 | "description" => $entry["description"], |
173 | "tex" => $entry['tex'], |
174 | "type" => $entry['type'], |
175 | ]; |
176 | } |
177 | break; |
178 | } |
179 | return $inputF; |
180 | } |
181 | |
182 | /** |
183 | * Reads the json file to an object |
184 | * @param string $filePath filepath to the json-file |
185 | * @return array |
186 | */ |
187 | private function getJSON( string $filePath ) { |
188 | $file = file_get_contents( $filePath ); |
189 | $json = json_decode( $file, true ); |
190 | return $json; |
191 | } |
192 | |
193 | public function writeToFile( string $fullPath, array $allEntries ): void { |
194 | $jsonData = json_encode( $allEntries, JSON_PRETTY_PRINT ); |
195 | file_put_contents( $fullPath, $jsonData ); |
196 | } |
197 | |
198 | /** |
199 | * Creates a renderer and fetches the generated MathML |
200 | * @param string $tex input tex |
201 | * @param string $type input type ('tex' or 'chem') |
202 | * @param string $renderingMode mode for rendering (latexml, mathml) |
203 | * @return string MathML as string |
204 | */ |
205 | public function fetchMathML( string $tex, string $type, string $renderingMode ): string { |
206 | $params = [ "type" => $type ]; |
207 | if ( $type == "chem" ) { |
208 | $params["chem"] = true; |
209 | $tex = "\\ce{ " . $tex . " }"; |
210 | } |
211 | /** @var MathRenderer $renderer */ |
212 | $renderer = $this->getServiceContainer()->get( 'Math.RendererFactory' ) |
213 | ->getRenderer( $tex, $params, $renderingMode ); |
214 | $renderer->render(); |
215 | $mml = $renderer->getMathml(); |
216 | return $mml; |
217 | } |
218 | } |
219 | |
220 | $maintClass = JsonToMathML::class; |
221 | require_once RUN_MAINTENANCE_IF_MAIN; |