Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
86.49% covered (warning)
86.49%
32 / 37
83.33% covered (warning)
83.33%
5 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
FQ
86.49% covered (warning)
86.49%
32 / 37
83.33% covered (warning)
83.33%
5 / 6
15.56
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getBase
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUp
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDown
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 render
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 renderMML
82.76% covered (warning)
82.76%
24 / 29
0.00% covered (danger)
0.00%
0 / 1
10.51
1<?php
2
3declare( strict_types = 1 );
4
5namespace MediaWiki\Extension\Math\WikiTexVC\Nodes;
6
7use MediaWiki\Extension\Math\WikiTexVC\MMLmappings\BaseParsing;
8use MediaWiki\Extension\Math\WikiTexVC\MMLnodes\MMLmrow;
9use MediaWiki\Extension\Math\WikiTexVC\MMLnodes\MMLmstyle;
10use MediaWiki\Extension\Math\WikiTexVC\MMLnodes\MMLmsubsup;
11use MediaWiki\Extension\Math\WikiTexVC\MMLnodes\MMLmunderover;
12use MediaWiki\Extension\Math\WikiTexVC\TexUtil;
13
14class FQ extends TexNode {
15
16    /** @var TexNode */
17    private $base;
18    /** @var TexNode */
19    private $up;
20    /** @var TexNode */
21    private $down;
22
23    public function __construct( TexNode $base, TexNode $down, TexNode $up ) {
24        parent::__construct( $base, $down, $up );
25        $this->base = $base;
26        $this->up = $up;
27        $this->down = $down;
28    }
29
30    /**
31     * @return TexNode
32     */
33    public function getBase(): TexNode {
34        return $this->base;
35    }
36
37    /**
38     * @return TexNode
39     */
40    public function getUp(): TexNode {
41        return $this->up;
42    }
43
44    /**
45     * @return TexNode
46     */
47    public function getDown(): TexNode {
48        return $this->down;
49    }
50
51    public function render() {
52        return $this->base->render() . '_' . $this->down->inCurlies() . '^' . $this->up->inCurlies();
53    }
54
55    public function renderMML( $arguments = [], $state = [] ) {
56        if ( array_key_exists( "limits", $state ) ) {
57            // A specific FQ case with preceding limits, just invoke the limits parsing manually.
58            return BaseParsing::limits( $this, $arguments, $state, "" );
59        }
60
61        if ( $this->getArgs()[0]->getLength() == 0 ) {
62            // this happens when FQ is located in Sideset (is this a common parsing way?)
63            $mrow = new MMLmrow();
64            return $mrow->encapsulateRaw( $this->getDown()->renderMML( [], $state ) ) .
65                $mrow->encapsulateRaw( $this->getUp()->renderMML( [], $state ) );
66        }
67
68        // Not sure if this case is necessary ..
69        if ( is_string( $this->getArgs()[0] ) ) {
70            return $this->parseToMML( $this->getArgs()[0], $arguments, null );
71        }
72
73        $melement = new MMLmsubsup();
74        // tbd check for more such cases like TexUtilTest 317
75        $base = $this->getBase();
76        if ( $base instanceof Literal ) {
77            $litArg = trim( $this->getBase()->getArgs()[0] );
78            $tu = TexUtil::getInstance();
79            // "sum", "bigcap", "bigcup", "prod" ... all are nullary macros.
80            if ( $tu->nullary_macro( $litArg ) && !$tu->is_literal( $litArg ) ) {
81                $melement = new MMLmunderover();
82            }
83        }
84
85        $mrow = new MMLmrow();
86        $emptyMrow = "";
87        // In cases with empty curly preceding like: "{}_1^2\!\Omega_3^4"
88        if ( $this->getBase() instanceof Curly && $this->getBase()->isEmpty() ) {
89            $emptyMrow = $mrow->getEmpty();
90        }
91        // This seems to be the common case
92        $inner = $melement->encapsulateRaw(
93            $emptyMrow .
94            $this->getBase()->renderMML( [], $state ) .
95            $mrow->encapsulateRaw( $this->getDown()->renderMML( $arguments, $state ) ) .
96            $mrow->encapsulateRaw( $this->getUp()->renderMML( $arguments, $state ) ) );
97
98        if ( $melement instanceof MMLmunderover ) {
99            $args = $state['styleargs'] ?? [ "displaystyle" => "true", "scriptlevel" => 0 ];
100            $style = new MMLmstyle( "", $args );
101            return $style->encapsulateRaw( $inner );
102        }
103
104        return $inner;
105    }
106}