Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
91.49% covered (success)
91.49%
43 / 47
62.50% covered (warning)
62.50%
5 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
DQ
91.49% covered (success)
91.49%
43 / 47
62.50% covered (warning)
62.50%
5 / 8
30.55
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
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
 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
94.44% covered (success)
94.44%
17 / 18
0.00% covered (danger)
0.00%
0 / 1
10.02
 extractIdentifiers
81.82% covered (warning)
81.82%
9 / 11
0.00% covered (danger)
0.00%
0 / 1
8.38
 extractSubscripts
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getModIdent
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
5.07
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\MMLmsub;
12use MediaWiki\Extension\Math\WikiTexVC\MMLnodes\MMLmunder;
13use MediaWiki\Extension\Math\WikiTexVC\TexUtil;
14
15class DQ extends TexNode {
16    /** @var TexNode */
17    private $base;
18    /** @var TexNode */
19    private $down;
20
21    public function __construct( TexNode $base, TexNode $down ) {
22        parent::__construct( $base, $down );
23        $this->base = $base;
24        $this->down = $down;
25    }
26
27    /**
28     * @return TexNode
29     */
30    public function getBase(): TexNode {
31        return $this->base;
32    }
33
34    /**
35     * @return TexNode
36     */
37    public function getDown(): TexNode {
38        return $this->down;
39    }
40
41    /** @inheritDoc */
42    public function render() {
43        return $this->base->render() . '_' . $this->down->inCurlies();
44    }
45
46    /** @inheritDoc */
47    public function toMMLTree( $arguments = [], &$state = [] ) {
48        if ( array_key_exists( "limits", $state ) ) {
49            // A specific DQ case with preceding limits, just invoke the limits parsing manually.
50            return BaseParsing::limits( $this, $arguments, $state, "" );
51        }
52
53        if ( $this->isEmpty() ) {
54            return null;
55        }
56        if ( $this->getBase()->containsFunc( "\underbrace" ) ) {
57            $outer = new MMLmunder();
58        } else {
59            $outer = new MMLmsub();
60            if ( ( $state['styleargs']['displaystle'] ?? 'true' ) === 'true' ) {
61                $tu = TexUtil::getInstance();
62                if ( $tu->operator( trim( $this->base->render() ) ) ) {
63                    $outer = new MMLmunder();
64                }
65            }
66        }
67        // Otherwise use default fallback
68        $inner_state = [ 'styleargs' => $state['styleargs'] ?? [] ];
69        $baseRendering = $this->base->toMMLTree( $arguments, $inner_state );
70        // In cases with empty curly preceding like: "{}_pF_q" or _{1}
71        if ( $baseRendering == null || $baseRendering === " " ||
72            ( $baseRendering instanceof MMLarray && !$baseRendering->hasChildren() ) ) {
73            $baseRendering = new MMLmrow();
74        }
75        return $outer::newSubtree( $baseRendering, new MMLmrow( TexClass::ORD, [], $this->down->toMMLTree(
76            $arguments, $state ) ) );
77    }
78
79    /** @inheritDoc */
80    public function extractIdentifiers( $args = null ) {
81        $d = $this->down->extractSubscripts();
82        $b = $this->base->extractIdentifiers();
83        if ( is_array( $b ) && count( $b ) > 1 ) {
84            return parent::extractIdentifiers();
85        }
86
87        if ( isset( $b[0] ) && $b[0] === '\'' ) {
88            return array_merge( $b, $d );
89        }
90
91        if ( isset( $d[0] ) && isset( $b[0] ) ) {
92            if ( $b[0] === '\\int' ) {
93                return array_merge( $b, $d );
94            }
95            return [ $b[0] . '_{' . $d[0] . '}' ];
96        }
97
98        return parent::extractIdentifiers();
99    }
100
101    /** @inheritDoc */
102    public function extractSubscripts() {
103        $d = array_merge( [], $this->down->extractSubscripts() );
104        $b = $this->base->extractSubscripts();
105        if ( isset( $b[0] ) && isset( $d[0] ) ) {
106            return [ $b[0] . '_{' . implode( '', $d ) . '}' ];
107        }
108        return parent::extractSubscripts();
109    }
110
111    /** @inheritDoc */
112    public function getModIdent() {
113        $d = $this->down->extractSubscripts();
114        $b = $this->base->getModIdent();
115        if ( isset( $b[0] ) && $b[0] === '\'' ) {
116            return [];
117        }
118        if ( isset( $d[0] ) && isset( $b[0] ) ) {
119            return [ $b[0] . '_{' . $d[0] . '}' ];
120        }
121
122        return parent::getModIdent();
123    }
124
125}