Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
68 / 68
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
MathML
100.00% covered (success)
100.00%
68 / 68
100.00% covered (success)
100.00%
3 / 3
22
100.00% covered (success)
100.00%
1 / 1
 write
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
2
 writeElementItem
100.00% covered (success)
100.00%
37 / 37
100.00% covered (success)
100.00%
1 / 1
11
 getElementTagName
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
9
1<?php
2
3namespace PhpOffice\Math\Writer;
4
5use PhpOffice\Math\Element;
6use PhpOffice\Math\Exception\NotImplementedException;
7use PhpOffice\Math\Math;
8use XMLWriter;
9
10class MathML implements WriterInterface
11{
12    /** @var XMLWriter */
13    private $output;
14
15    /**
16     * @param Math $math
17     *
18     * @return string
19     */
20    public function write(Math $math): string
21    {
22        $this->output = new XMLWriter();
23        $this->output->openMemory();
24        $this->output->startDocument('1.0', 'UTF-8');
25        $this->output->writeDtd('math', '-//W3C//DTD MathML 2.0//EN', 'http://www.w3.org/Math/DTD/mathml2/mathml2.dtd');
26        $this->output->startElement('math');
27        $this->output->writeAttribute('xmlns', 'http://www.w3.org/1998/Math/MathML');
28
29        foreach ($math->getElements() as $element) {
30            $this->writeElementItem($element);
31        }
32
33        $this->output->endElement();
34        $this->output->endDocument();
35
36        return $this->output->outputMemory();
37    }
38
39    protected function writeElementItem(Element\AbstractElement $element): void
40    {
41        $tagName = $this->getElementTagName($element);
42
43        // Element\AbstractGroupElement
44        if ($element instanceof Element\Semantics) {
45            $this->output->startElement($tagName);
46            // Write elements
47            foreach ($element->getElements() as $childElement) {
48                $this->writeElementItem($childElement);
49            }
50
51            // Write annotations
52            foreach ($element->getAnnotations() as $encoding => $annotation) {
53                $this->output->startElement('annotation');
54                $this->output->writeAttribute('encoding', $encoding);
55                $this->output->text($annotation);
56                $this->output->endElement();
57            }
58            $this->output->endElement();
59
60            return;
61        }
62
63        // Element\AbstractGroupElement
64        if ($element instanceof Element\AbstractGroupElement) {
65            $this->output->startElement($tagName);
66            foreach ($element->getElements() as $childElement) {
67                $this->writeElementItem($childElement);
68            }
69            $this->output->endElement();
70
71            return;
72        }
73
74        // Element\Superscript
75        if ($element instanceof Element\Superscript) {
76            $this->output->startElement($tagName);
77            $this->writeElementItem($element->getBase());
78            $this->writeElementItem($element->getSuperscript());
79            $this->output->endElement();
80
81            return;
82        }
83
84        // Element\Fraction
85        if ($element instanceof Element\Fraction) {
86            $this->output->startElement($tagName);
87            $this->writeElementItem($element->getNumerator());
88            $this->writeElementItem($element->getDenominator());
89            $this->output->endElement();
90
91            return;
92        }
93
94        if ($element instanceof Element\Identifier
95          || $element instanceof Element\Numeric
96          || $element instanceof Element\Operator) {
97            $this->output->startElement($tagName);
98            $this->output->text((string) $element->getValue());
99            $this->output->endElement();
100
101            return;
102        }
103
104        /*
105        throw new NotImplementedException(sprintf(
106            '%s : The class `%s` is not implemented',
107            __METHOD__,
108            get_class($element)
109        ));
110        */
111    }
112
113    protected function getElementTagName(Element\AbstractElement $element): string
114    {
115        // Group
116        if ($element instanceof Element\Row) {
117            return 'mrow';
118        }
119        if ($element instanceof Element\AbstractGroupElement) {
120            /*
121            throw new NotImplementedException(sprintf(
122                '%s : The element of the class `%s` has no tag name',
123                __METHOD__,
124                get_class($element)
125            ));
126            */
127        }
128
129        if ($element instanceof Element\Superscript) {
130            return 'msup';
131        }
132        if ($element instanceof Element\Fraction) {
133            return 'mfrac';
134        }
135        if ($element instanceof Element\Identifier) {
136            return 'mi';
137        }
138        if ($element instanceof Element\Numeric) {
139            return 'mn';
140        }
141        if ($element instanceof Element\Operator) {
142            return 'mo';
143        }
144        if ($element instanceof Element\Semantics) {
145            return 'semantics';
146        }
147
148        throw new NotImplementedException(sprintf(
149            '%s : The element of the class `%s` has no tag name',
150            __METHOD__,
151            get_class($element)
152        ));
153    }
154}