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