1
0
mirror of https://github.com/php/phd.git synced 2026-03-23 22:52:05 +01:00

Support MathML (mml:*) elements for XHTML rendering (#236)

Closes #172
This commit is contained in:
Louis-Arnaud
2026-02-05 18:04:33 +01:00
committed by GitHub
parent 3572bd3dd2
commit 61ad3e7cb0
4 changed files with 146 additions and 0 deletions

View File

@@ -392,6 +392,48 @@ abstract class Package_Generic_XHTML extends Format_Abstract_XHTML {
//phd
'phd:toc' => 'format_phd_toc',
// MathML (namespace http://www.w3.org/1998/Math/MathML)
'mml:math' => 'format_mml_element',
// Token
'mml:mi' => 'format_mml_element',
'mml:mn' => 'format_mml_element',
'mml:mo' => 'format_mml_element',
'mml:mtext' => 'format_mml_element',
'mml:mspace' => 'format_mml_element',
'mml:ms' => 'format_mml_element',
// Layout
'mml:mrow' => 'format_mml_element',
'mml:mfrac' => 'format_mml_element',
'mml:msqrt' => 'format_mml_element',
'mml:mroot' => 'format_mml_element',
'mml:mstyle' => 'format_mml_element',
'mml:merror' => 'format_mml_element',
'mml:mpadded' => 'format_mml_element',
'mml:mphantom' => 'format_mml_element',
'mml:mfenced' => 'format_mml_element',
'mml:menclose' => 'format_mml_element',
// Scripts and limits
'mml:msub' => 'format_mml_element',
'mml:msup' => 'format_mml_element',
'mml:msubsup' => 'format_mml_element',
'mml:munder' => 'format_mml_element',
'mml:mover' => 'format_mml_element',
'mml:munderover' => 'format_mml_element',
'mml:mmultiscripts' => 'format_mml_element',
'mml:mprescripts' => 'format_mml_element',
'mml:none' => 'format_mml_element',
// Tables
'mml:mtable' => 'format_mml_element',
'mml:mtr' => 'format_mml_element',
'mml:mtd' => 'format_mml_element',
'mml:mlabeledtr' => 'format_mml_element',
// Semantics
'mml:semantics' => 'format_mml_element',
'mml:annotation' => 'format_mml_element',
'mml:annotation-xml' => 'format_mml_element',
// Actions
'mml:maction' => 'format_mml_element',
); /* }}} */
private $mytextmap = array(
@@ -631,6 +673,37 @@ abstract class Package_Generic_XHTML extends Format_Abstract_XHTML {
) . "</div>\n";
}
/**
* Handle MathML elements (mml:* namespace).
* Strips the "mml:" prefix and outputs the HTML5 local name.
*/
public function format_mml_element($open, $name, $attrs, $props) {
$localName = substr($name, 4);
if ($open) {
$attrStr = '';
// Add xmlns on the <math> root element for XHTML compatibility
if ($localName === 'math') {
$attrStr .= ' xmlns="' . Reader::XMLNS_MATHML . '"';
}
// Preserve MathML attributes (stored under XMLNS_DOCBOOK as they have no namespace)
foreach ($attrs[Reader::XMLNS_DOCBOOK] as $attr => $val) {
$attrStr .= ' ' . $attr . '="' . $this->TEXT($val) . '"';
}
// Preserve xml:id as id
if (isset($attrs[Reader::XMLNS_XML]["id"])) {
$attrStr .= ' id="' . $attrs[Reader::XMLNS_XML]["id"] . '"';
}
return '<' . $localName . $attrStr . ($props["empty"] ? '/>' : '>');
}
return '</' . $localName . '>';
}
public function createLink($for, &$desc = null, $type = Format::SDESC) {
$retval = null;
if (isset($this->indexes[$for])) {

View File

@@ -7,6 +7,7 @@ class Reader extends \XMLReader
const XMLNS_XLINK = "http://www.w3.org/1999/xlink";
const XMLNS_PHD = "http://www.php.net/ns/phd";
const XMLNS_DOCBOOK = "http://docbook.org/ns/docbook";
const XMLNS_MATHML = "http://www.w3.org/1998/Math/MathML";
protected OutputHandler $outputHandler;

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<chapter xml:id="mathml_rendering" xmlns="http://docbook.org/ns/docbook" xmlns:mml="http://www.w3.org/1998/Math/MathML">
<section>
<para>1. Inline MathML equation</para>
<para>
The quadratic formula is
<mml:math display="inline"><mml:mi>x</mml:mi><mml:mo>=</mml:mo><mml:mfrac><mml:mrow><mml:mo>-</mml:mo><mml:mi>b</mml:mi><mml:mo>±</mml:mo><mml:msqrt><mml:mrow><mml:msup><mml:mi>b</mml:mi><mml:mn>2</mml:mn></mml:msup><mml:mo>-</mml:mo><mml:mn>4</mml:mn><mml:mi>a</mml:mi><mml:mi>c</mml:mi></mml:mrow></mml:msqrt></mml:mrow><mml:mrow><mml:mn>2</mml:mn><mml:mi>a</mml:mi></mml:mrow></mml:mfrac></mml:math>.
</para>
</section>
<section>
<para>2. Self-closing mspace element</para>
<para>
<mml:math><mml:mi>a</mml:mi><mml:mspace width="1em"/><mml:mi>b</mml:mi></mml:math>
</para>
</section>
<section>
<para>3. Element with mathvariant attribute</para>
<para>
<mml:math><mml:mi mathvariant="bold">x</mml:mi></mml:math>
</para>
</section>
</chapter>

View File

@@ -0,0 +1,46 @@
--TEST--
MathML rendering
--FILE--
<?php
namespace phpdotnet\phd;
require_once __DIR__ . "/../../setup.php";
$xmlFile = __DIR__ . "/data/mathml_rendering.xml";
$config->xmlFile = $xmlFile;
$format = new TestPHPChunkedXHTML($config, $outputHandler);
$render = new TestRender(new Reader($outputHandler), $config, $format);
$render->run();
?>
--EXPECT--
Filename: mathml_rendering.html
Content:
<div id="mathml_rendering" class="chapter">
<div class="section">
<p class="para">1. Inline MathML equation</p>
<p class="para">
The quadratic formula is
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mi>x</mi><mo>=</mo><mfrac><mrow><mo>-</mo><mi>b</mi><mo>±</mo><msqrt><mrow><msup><mi>b</mi><mn>2</mn></msup><mo>-</mo><mn>4</mn><mi>a</mi><mi>c</mi></mrow></msqrt></mrow><mrow><mn>2</mn><mi>a</mi></mrow></mfrac></math>.
</p>
</div>
<div class="section">
<p class="para">2. Self-closing mspace element</p>
<p class="para">
<math xmlns="http://www.w3.org/1998/Math/MathML"><mi>a</mi><mspace width="1em"/><mi>b</mi></math>
</p>
</div>
<div class="section">
<p class="para">3. Element with mathvariant attribute</p>
<p class="para">
<math xmlns="http://www.w3.org/1998/Math/MathML"><mi mathvariant="bold">x</mi></math>
</p>
</div>
</div>