Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
89.19% covered (warning)
89.19%
33 / 37
83.33% covered (warning)
83.33%
5 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
FQ
89.19% covered (warning)
89.19%
33 / 37
83.33% covered (warning)
83.33%
5 / 6
16.32
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
86.21% covered (warning)
86.21%
25 / 29
0.00% covered (danger)
0.00%
0 / 1
11.32
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    /** @inheritDoc */
52    public function render() {
53        return $this->base->render() . '_' . $this->down->inCurlies() . '^' . $this->up->inCurlies();
54    }
55
56    /** @inheritDoc */
57    public function renderMML( $arguments = [], &$state = [] ) {
58        if ( array_key_exists( "limits", $state ) ) {
59            // A specific FQ case with preceding limits, just invoke the limits parsing manually.
60            return BaseParsing::limits( $this, $arguments, $state, "" );
61        }
62        $base = $this->getBase();
63
64        if ( $base->getLength() == 0 && !$base->isCurly() ) {
65            // this happens when FQ is located in Sideset (is this a common parsing way?)
66            $mrow = new MMLmrow();
67            return $mrow->encapsulateRaw( $this->getDown()->renderMML( [], $state ) ) .
68                $mrow->encapsulateRaw( $this->getUp()->renderMML( [], $state ) );
69        }
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        $mrow = new MMLmrow();
87        $emptyMrow = "";
88        // In cases with empty curly preceding like: "{}_1^2\!\Omega_3^4"
89        if ( $base->isCurly() && $base->isEmpty() ) {
90            $emptyMrow = $mrow->getEmpty();
91        }
92        // This seems to be the common case
93        $inner = $melement->encapsulateRaw(
94            $emptyMrow .
95            $base->renderMML( [], $state ) .
96            $mrow->encapsulateRaw( $this->getDown()->renderMML( $arguments, $state ) ) .
97            $mrow->encapsulateRaw( $this->getUp()->renderMML( $arguments, $state ) ) );
98
99        if ( $melement instanceof MMLmunderover ) {
100            $args = $state['styleargs'] ?? [ "displaystyle" => "true", "scriptlevel" => 0 ];
101            $style = new MMLmstyle( "", $args );
102            return $style->encapsulateRaw( $inner );
103        }
104
105        return $inner;
106    }
107}