Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
68 / 68 |
|
100.00% |
3 / 3 |
CRAP | |
100.00% |
1 / 1 |
MathML | |
100.00% |
68 / 68 |
|
100.00% |
3 / 3 |
22 | |
100.00% |
1 / 1 |
write | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
2 | |||
writeElementItem | |
100.00% |
37 / 37 |
|
100.00% |
1 / 1 |
11 | |||
getElementTagName | |
100.00% |
20 / 20 |
|
100.00% |
1 / 1 |
9 |
1 | <?php |
2 | |
3 | namespace PhpOffice\Math\Writer; |
4 | |
5 | use PhpOffice\Math\Element; |
6 | use PhpOffice\Math\Exception\NotImplementedException; |
7 | use PhpOffice\Math\Math; |
8 | use XMLWriter; |
9 | |
10 | class 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 | } |