Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
17.91% |
12 / 67 |
|
54.55% |
6 / 11 |
CRAP | |
0.00% |
0 / 1 |
MMLutil | |
17.91% |
12 / 67 |
|
54.55% |
6 / 11 |
673.47 | |
0.00% |
0 / 1 |
initalParseLiteralExpression | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
uc2xNotation | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
number2xNotation | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
round2em | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
size2em | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
squashLitsToUnit | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
addPreOperator | |
0.00% |
0 / 21 |
|
0.00% |
0 / 1 |
90 | |||
dimen2em | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
30 | |||
createEntity | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
squashLitsToUnitIntent | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
56 | |||
removeDollarEscaping | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | namespace MediaWiki\Extension\Math\WikiTexVC\MMLmappings\Util; |
3 | |
4 | use IntlChar; |
5 | use MediaWiki\Extension\Math\WikiTexVC\Nodes\DQ; |
6 | use MediaWiki\Extension\Math\WikiTexVC\Nodes\Literal; |
7 | use MediaWiki\Extension\Math\WikiTexVC\Nodes\TexArray; |
8 | use MediaWiki\Extension\Math\WikiTexVC\Nodes\TexNode; |
9 | |
10 | /** |
11 | * Utility Methods for parsing Tex to MathML |
12 | * @author Johannes Stegmüller |
13 | */ |
14 | class MMLutil { |
15 | /** |
16 | * Splits a regular expression in the form '\operatorname {someparams} |
17 | * Also recognizes succeeding parentheses '\operatorname (' as params |
18 | * @param string $input tex expression |
19 | * @return array|null found groups or null |
20 | */ |
21 | public static function initalParseLiteralExpression( $input ): ?array { |
22 | $pattern = "/([\\a-zA-Z\s]+)\{([^}]+)\}/"; |
23 | $matches = []; |
24 | $matched = preg_match_all( $pattern, $input, $matches ); |
25 | return $matched ? $matches : null; |
26 | } |
27 | |
28 | /** |
29 | * Recognize if input is a Unicode string "\\u1235" |
30 | * If yes converts it to notation "ģ", if no just returns the input. |
31 | * @param string $input input to be checked |
32 | * @return string modified input or input |
33 | */ |
34 | public static function uc2xNotation( string $input ): string { |
35 | if ( str_starts_with( $input, "\\u" ) ) { |
36 | return str_replace( "\\u", "&#x", $input ) . ";"; |
37 | } |
38 | return $input; |
39 | } |
40 | |
41 | public static function number2xNotation( string $input ): string { |
42 | return "&#x" . $input . ";"; |
43 | } |
44 | |
45 | /** |
46 | * Rounds a floating point input to three digits precision |
47 | * and returns it as string with succeeding "em". |
48 | * @param float $size input to be processed |
49 | * @return string rounded digits with em |
50 | */ |
51 | public static function round2em( float $size ) { |
52 | $rounded = round( $size, 3 ); |
53 | return $rounded . "em"; |
54 | } |
55 | |
56 | /** |
57 | * In a floating point digit as string, set input to precision of three digits |
58 | * without rounding. |
59 | * @param string $size input to be checked |
60 | * @return string digits of precision three with em |
61 | */ |
62 | public static function size2em( string $size ): string { |
63 | return preg_replace( "/(\.\d\d\d).+/", '$1', $size ) . "em"; |
64 | } |
65 | |
66 | /** |
67 | * Assumes the input curly contains an TexArray of literals, squashes the TexArray characters to a string. |
68 | * @param TexArray $node TexArray of literals |
69 | * @return ?string squashed string in example "2mu", "-3mu" etc. Null if no TexArray inside curly. |
70 | */ |
71 | public static function squashLitsToUnit( TexArray $node ): ?string { |
72 | $unit = ""; |
73 | foreach ( $node as $literal ) { |
74 | if ( !$literal instanceof Literal ) { |
75 | continue; |
76 | } |
77 | $unit .= $literal->getArg(); |
78 | } |
79 | |
80 | return $unit; |
81 | } |
82 | |
83 | /** |
84 | * em or other dimensional unit gets multiplied by pre-operator. |
85 | * @param string $size input size i.e-123em |
86 | * @param string $operator plus (+) or minus (-) |
87 | * @return string ++ => + , -- => +, -+ => - |
88 | */ |
89 | public static function addPreOperator( string $size, string $operator ): string { |
90 | $emtr = trim( $size ); |
91 | |
92 | $ok = preg_match( "/^([+\-])$/", $operator ); |
93 | if ( !$ok ) { |
94 | return ''; |
95 | } |
96 | switch ( $emtr[0] ) { |
97 | case "-": |
98 | if ( $operator == "+" ) { |
99 | return $emtr; |
100 | } elseif ( $operator == "-" ) { |
101 | $emtr[0] = "+"; |
102 | return $emtr; |
103 | } |
104 | break; |
105 | case "+": |
106 | if ( $operator == "+" ) { |
107 | return $emtr; |
108 | } elseif ( $operator == "-" ) { |
109 | $emtr[0] = "-"; |
110 | return $emtr; |
111 | } |
112 | break; |
113 | default: |
114 | return $operator . $emtr; |
115 | } |
116 | return $emtr; |
117 | } |
118 | |
119 | /** |
120 | * Convert a length dimension to em format |
121 | * currently supports "mu: math unit and forwards em" |
122 | * @param string $dimen input for length dimension like "-2mu" or "3 em" |
123 | * @return string|null converted string i.e. "0.333em" or null if error |
124 | */ |
125 | public static function dimen2em( string $dimen ): ?string { |
126 | $matches = []; |
127 | $matched = preg_match( '/([+-]?)(\d*\.*\d+)\s*(mu|em)/', $dimen, $matches ); |
128 | |
129 | if ( !$matched ) { |
130 | return null; |
131 | } |
132 | if ( $matches[3] == "mu" ) { |
133 | $ret = self::size2em( strval( intval( $matches[2] ) / 18 ) ); |
134 | } elseif ( $matches[3] == "em" ) { |
135 | $ret = $matches[2] . "em"; |
136 | } else { |
137 | return null; |
138 | } |
139 | |
140 | return ( $matches[1] == "-" ? "-" : "" ) . $ret; |
141 | } |
142 | |
143 | public static function createEntity( string $code ): ?string { |
144 | return IntlChar::chr( intval( $code, 16 ) ); |
145 | } |
146 | |
147 | /** |
148 | * Assumes the input curly contains an TexArray of literals, squashes the TexArray characters to a string. |
149 | * It checks for dollar escaping and removes a backslash, also renders DQ args with underscores |
150 | * @param TexNode $node curly containing a TexArray of literals |
151 | * @return ?string squashed string in example "2mu", "-3mu" etc. Null if no TexArray inside curly. |
152 | */ |
153 | public static function squashLitsToUnitIntent( TexNode $node ): ?string { |
154 | if ( !$node->isCurly() ) { |
155 | return null; |
156 | } |
157 | $unit = ""; |
158 | foreach ( $node->getArgs() as $literal ) { |
159 | if ( $literal instanceof DQ ) { |
160 | $args = $literal->getArgs(); |
161 | if ( !$args[0] instanceof Literal || !$args[1] instanceof Literal ) { |
162 | continue; |
163 | } |
164 | $arg = self::removeDollarEscaping( $args[0]->getArgs()[0] ) . "_" |
165 | . self::removeDollarEscaping( $args[1]->getArgs()[0] ); |
166 | } else { |
167 | if ( !$literal instanceof Literal ) { |
168 | continue; |
169 | } |
170 | $arg = self::removeDollarEscaping( $literal->getArg() ); |
171 | } |
172 | $unit .= $arg; |
173 | } |
174 | return $unit; |
175 | } |
176 | |
177 | public static function removeDollarEscaping( string $input ): string { |
178 | if ( $input == "\\$" ) { |
179 | return "\$"; |
180 | } |
181 | return $input; |
182 | } |
183 | |
184 | } |