diff --git a/src/Math/Element/Semantics.php b/src/Math/Element/Semantics.php new file mode 100644 index 0000000..be3ec56 --- /dev/null +++ b/src/Math/Element/Semantics.php @@ -0,0 +1,33 @@ + + */ + protected $annotations = []; + + public function addAnnotation(string $encoding, string $annotation): self + { + $this->annotations[$encoding] = $annotation; + + return $this; + } + + public function getAnnotation(string $encoding): ?string + { + return $this->annotations[$encoding] ?? null; + } + + /** + * @return array + */ + public function getAnnotations(): array + { + return $this->annotations; + } +} diff --git a/src/Math/Reader/MathML.php b/src/Math/Reader/MathML.php index 8a370d9..21185fe 100644 --- a/src/Math/Reader/MathML.php +++ b/src/Math/Reader/MathML.php @@ -49,6 +49,17 @@ protected function parseNode(?DOMNode $nodeRowElement, $parent): void { $this->xpath = new DOMXpath($this->dom); foreach ($this->xpath->query('*', $nodeRowElement) ?: [] as $nodeElement) { + if ($parent instanceof Element\Semantics + && $nodeElement instanceof DOMElement + && $nodeElement->nodeName == 'annotation') { + $parent->addAnnotation( + $nodeElement->getAttribute('encoding'), + trim($nodeElement->nodeValue) + ); + + continue; + } + $element = $this->getElement($nodeElement); $parent->add($element); @@ -103,6 +114,8 @@ protected function getElement(DOMNode $nodeElement): Element\AbstractElement } return $element; + case 'semantics': + return new Element\Semantics(); default: throw new Exception(sprintf( '%s : The tag `%s` is not implemented', diff --git a/tests/Math/Reader/MathMLTest.php b/tests/Math/Reader/MathMLTest.php index 617a746..69483d3 100644 --- a/tests/Math/Reader/MathMLTest.php +++ b/tests/Math/Reader/MathMLTest.php @@ -151,4 +151,49 @@ public function testReadFraction(): void $this->assertInstanceOf(Element\Identifier::class, $denominator); $this->assertEquals('d', $denominator->getValue()); } + + /** + * @covers \MathML::read + */ + public function testReadSemantics(): void + { + $content = ' + + + + + π + 2 + + + + + a + + 2 + + + {π} over {2} + { a } * 2 + + '; + + $reader = new MathML(); + $math = $reader->read($content); + $this->assertInstanceOf(Math::class, $math); + + $elements = $math->getElements(); + $this->assertCount(1, $elements); + $this->assertInstanceOf(Element\Semantics::class, $elements[0]); + + /** @var Element\Semantics $element */ + $element = $elements[0]; + + // Check MathML + $subElements = $element->getElements(); + $this->assertCount(1, $subElements); + $this->assertInstanceOf(Element\Row::class, $subElements[0]); + + // Check Annotation + $this->assertCount(1, $element->getAnnotations()); + $this->assertEquals('{π} over {2} + { a } * 2', $element->getAnnotation('StarMath 5.0')); + } }