Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
MathFormatter
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
4 / 4
11
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 format
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
8
 formatDetails
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 getFormat
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace MediaWiki\Extension\Math;
4
5use DataValues\StringValue;
6use InvalidArgumentException;
7use MediaWiki\Html\Html;
8use ValueFormatters\ValueFormatter;
9use Wikibase\Lib\Formatters\SnakFormatter;
10
11/**
12 * Formats the tex string based on the known formats
13 * - text/plain: used in the value input field of Wikidata
14 * - text/x-wiki: wikitext
15 * - text/html: used in Wikidata to display the value of properties
16 * Formats can look like this: "text/html; disposition=diff"
17 * or just "text/plain"
18 */
19class MathFormatter implements ValueFormatter {
20
21    /**
22     * Loads format to distinguish the type of formatting
23     *
24     * @param string $format One of the SnakFormatter::FORMAT_... constants.
25     */
26    public function __construct(
27        private readonly string $format,
28    ) {
29    }
30
31    /**
32     * @param StringValue $value
33     *
34     * @throws InvalidArgumentException if not called with a StringValue
35     * @return string
36     */
37    public function format( $value ) {
38        if ( !( $value instanceof StringValue ) ) {
39            throw new InvalidArgumentException( '$value must be a StringValue' );
40        }
41
42        $tex = $value->getValue();
43
44        switch ( $this->format ) {
45            case SnakFormatter::FORMAT_PLAIN:
46                return $tex;
47            case SnakFormatter::FORMAT_WIKI:
48                return "<math>$tex</math>";
49
50            // Intentionally fall back to MathML output in all other, possibly unknown cases.
51            default:
52                $renderer = new MathNativeMML( $tex );
53
54                if ( $renderer->checkTeX() && $renderer->render() ) {
55                    $html = $renderer->getHtmlOutput();
56                } else {
57                    $html = $renderer->getLastError();
58                }
59
60                if ( $this->format === SnakFormatter::FORMAT_HTML_DIFF ) {
61                    $html = $this->formatDetails( $html, $tex );
62                }
63
64                return $html;
65        }
66    }
67
68    /**
69     * Constructs a detailed HTML rendering for use in diff views.
70     *
71     * @param string $valueHtml
72     * @param string $tex
73     *
74     * @return string HTML
75     */
76    private function formatDetails( $valueHtml, $tex ) {
77        $html = Html::rawElement( 'h4',
78            [ 'class' => 'wb-details wb-math-details wb-math-rendered' ],
79            $valueHtml
80        );
81
82        $html .= Html::rawElement( 'div',
83            [ 'class' => 'wb-details wb-math-details' ],
84            Html::element( 'code', [], $tex )
85        );
86
87        return $html;
88    }
89
90    /**
91     * @return string One of the SnakFormatter::FORMAT_... constants.
92     */
93    public function getFormat() {
94        return $this->format;
95    }
96
97}