Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
35.71% covered (danger)
35.71%
10 / 28
60.00% covered (warning)
60.00%
3 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
ScoreFormatter
35.71% covered (danger)
35.71%
10 / 28
60.00% covered (warning)
60.00%
3 / 5
25.00
0.00% covered (danger)
0.00%
0 / 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%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 formatAsHtml
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
12
 formatDetails
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 getFormat
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/*
3  Score, a MediaWiki extension for rendering musical scores with LilyPond.
4  Copyright © 2011 Alexander Klauer
5
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15
16  You should have received a copy of the GNU General Public License
17  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19*/
20
21namespace MediaWiki\Extension\Score;
22
23use DataValues\StringValue;
24use InvalidArgumentException;
25use MediaWiki\Config\Config;
26use MediaWiki\Html\Html;
27use ValueFormatters\ValueFormatter;
28use Wikibase\Lib\Formatters\SnakFormatter;
29
30/**
31 * Formats Lilypond string based on the known formats
32 * - text/plain: used in the value input field of Wikidata
33 * - text/x-wiki: wikitext
34 * - text/html: used in Wikidata to display the value of properties
35 * Formats can look like this: "text/html; disposition=diff"
36 * or just "text/plain"
37 */
38class ScoreFormatter implements ValueFormatter {
39
40    /**
41     * Loads format to distinguish the type of formatting
42     *
43     * @param Config $config
44     * @param string $format One of the SnakFormatter::FORMAT_... constants.
45     */
46    public function __construct(
47        private readonly Config $config,
48        private readonly string $format,
49    ) {
50    }
51
52    /**
53     * @param StringValue $value
54     *
55     * @throws InvalidArgumentException if not called with a StringValue
56     * @return string
57     */
58    public function format( $value ) {
59        if ( !( $value instanceof StringValue ) ) {
60            throw new InvalidArgumentException( '$value must be a StringValue' );
61        }
62
63        $valueString = $value->getValue();
64
65        return match ( $this->format ) {
66            SnakFormatter::FORMAT_PLAIN => $valueString,
67            SnakFormatter::FORMAT_WIKI => "<score>$valueString</score>",
68            default => $this->formatAsHtml( $valueString ),
69        };
70    }
71
72    private function formatAsHtml( string $valueString ): string {
73        $args = [];
74
75        $args['line_width_inches'] = $this->config->get( 'WikibaseMusicalNotationLineWidthInches' );
76
77        try {
78            $valueHtml = Score::renderScore(
79                $valueString,
80                $args
81            );
82        } catch ( ScoreException $exception ) {
83            return (string)$exception;
84        }
85
86        if ( $this->format === SnakFormatter::FORMAT_HTML_DIFF ) {
87            $valueHtml = $this->formatDetails( $valueHtml, $valueString );
88        }
89
90        return $valueHtml;
91    }
92
93    /**
94     * Constructs a detailed HTML rendering for use in diff views.
95     *
96     * @return string HTML
97     */
98    private function formatDetails( string $valueHtml, string $valueString ): string {
99        return Html::rawElement( 'h4',
100            [ 'class' => 'wb-details wb-musical-notation-details wb-musical-notation-rendered' ],
101            $valueHtml
102        ) . Html::rawElement( 'div',
103            [ 'class' => 'wb-details wb-musical-notation-details' ],
104            Html::element( 'code', [], $valueString )
105        );
106    }
107
108    /**
109     * @return string One of the SnakFormatter::FORMAT_... constants.
110     */
111    public function getFormat(): string {
112        return $this->format;
113    }
114
115}