Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
88.81% covered (warning)
88.81%
119 / 134
37.50% covered (danger)
37.50%
3 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
TexVC
88.81% covered (warning)
88.81%
119 / 134
37.50% covered (danger)
37.50%
3 / 8
52.37
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 parse
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 check
93.85% covered (success)
93.85%
61 / 65
0.00% covered (danger)
0.00%
0 / 1
24.13
 checkTreeIntents
76.19% covered (warning)
76.19%
16 / 21
0.00% covered (danger)
0.00%
0 / 1
12.63
 checkIntentArg
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
3.03
 checkIntent
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 handleTexError
88.46% covered (warning)
88.46%
23 / 26
0.00% covered (danger)
0.00%
0 / 1
5.04
 getLocationInfo
71.43% covered (warning)
71.43%
5 / 7
0.00% covered (danger)
0.00%
0 / 1
2.09
1<?php
2
3declare( strict_types = 1 );
4
5namespace MediaWiki\Extension\Math\WikiTexVC;
6
7use Exception;
8use MediaWiki\Extension\Math\WikiTexVC\Mhchem\MhchemParser;
9use MediaWiki\Extension\Math\WikiTexVC\MMLmappings\Util\MMLParsingUtil;
10use MediaWiki\Extension\Math\WikiTexVC\MMLmappings\Util\MMLutil;
11use MediaWiki\Extension\Math\WikiTexVC\Nodes\Fun2;
12use MediaWiki\Extension\Math\WikiTexVC\Nodes\TexArray;
13use MediaWiki\Extension\Math\WikiTexVC\Nodes\TexNode;
14use stdClass;
15
16/**
17 * A TeX/LaTeX validator and MathML converter.
18 * WikiTexVC takes user input and validates it while replacing
19 * MediaWiki-specific functions.  The validator component is a PHP port of the JavaScript port of texvc,
20 * which was originally written in Ocaml for the Math extension.
21 *
22 * @author Johannes Stegmüller
23 */
24class TexVC {
25    /** @var Parser */
26    private $parser;
27    /** @var TexUtil */
28    private $tu;
29
30    public function __construct() {
31        $this->parser = new Parser();
32        $this->tu = TexUtil::getInstance();
33    }
34
35    /**
36     * Usually this step is done implicitly within the check-method.
37     * @param string $input tex-string as input for the grammar
38     * @param null|array $options array options for the grammar.
39     * @return mixed output of the grammar.
40     * @throws SyntaxError when SyntaxError in the input
41     */
42    public function parse( $input, $options = null ) {
43        return $this->parser->parse( $input, $options );
44    }
45
46    /** status is one character:
47     *  + : success! result is in 'output'
48     *  E : Lexer exception raised
49     *  F : TeX function not recognized
50     *  S : Parsing error
51     *  - : Generic/Default failure code. Might be an invalid argument,
52     *      output file already exist, a problem with an external
53     *      command ...
54     * @param string|TexArray|stdClass $input tex to be checked as string,
55     * can also be the output of former parser call
56     * @param array $options array options for settings of the check
57     * @param array &$warnings reference on warnings occurring during the check
58     * @param bool $texifyMhchem create TeX for mhchem in input before checking further
59     * @return array|string[] output with information status (see above)
60     * @throws Exception in case of a major problem with the check and activated debug option.
61     */
62    public function check( $input, $options = [], &$warnings = [], bool $texifyMhchem = false ) {
63        try {
64            if ( $texifyMhchem && isset( $options["usemhchem"] ) && $options["usemhchem"] ) {
65                // Parse the chemical equations to TeX with mhChemParser in PHP as preprocessor
66                $mhChemParser = new MHChemParser();
67                $input = $mhChemParser->toTex( $input, "tex", true );
68            }
69
70            $options = ParserUtil::createOptions( $options );
71            if ( is_string( $input ) ) {
72                $input = $this->parser->parse( $input, $options );
73            }
74            $output = $input->render();
75
76            $result = [
77                'inputN' => $input,
78                'status' => '+',
79                'output' => $output,
80                'warnings' => $warnings,
81                'input' => $input,
82                'success' => true,
83            ];
84
85            if ( $options['report_required'] ) {
86                $pkgs = [ 'ams', 'cancel', 'color', 'euro', 'teubner',
87                        'mhchem', 'mathoid', 'mhchemtexified', "intent" ];
88
89                foreach ( $pkgs as $pkg ) {
90                    $pkg .= '_required';
91                    $tuRef = $this->tu->getBaseElements()[$pkg];
92                    $result[$pkg] = $input->containsFunc( $tuRef );
93                }
94            }
95
96            if ( !$options['usemhchem'] ) {
97                if ( $result['mhchem_required'] ??
98                        $input->containsFunc( $this->tu->getBaseElements()['mhchem_required'] )
99                ) {
100                    return [
101                        'status' => 'C',
102                        'details' => 'mhchem package required.'
103                    ];
104                }
105            }
106            if ( !$options['usemhchemtexified'] ) {