diff --git a/cnxpublishing/models.py b/cnxpublishing/models.py
index 32f89ac9..58aaa48e 100644
--- a/cnxpublishing/models.py
+++ b/cnxpublishing/models.py
@@ -11,6 +11,30 @@
from pyramid.threadlocal import get_current_registry
+MATHML_NAMESPACE = "http://www.w3.org/1998/Math/MathML"
+NSMAP = {'m': MATHML_NAMESPACE}
+
+
+def _find_or_create_semantics_block(math_block):
+ """Finds or creates the MathML semantics tag."""
+ try:
+ semantics_block = math_block.xpath(
+ '/m:samantics',
+ namespaces=NSMAP)[0]
+ except IndexError:
+ # Move all the contents of the math_block into a semantics wrapper.
+ children = []
+ for child in math_block.getchildren():
+ children.append(child)
+ math_block.remove(child) # why no pop?
+ semantics_block = etree.SubElement(
+ math_block,
+ '{{{}}}semantics'.format(MATHML_NAMESPACE))
+ for child in children:
+ semantics_block.append(child)
+ return semantics_block
+
+
def inject_mathml_svgs(content):
"""Inject MathML SVG annotations into HTML content."""
settings = get_current_registry().settings
@@ -22,24 +46,23 @@ def inject_mathml_svgs(content):
return content
xml = etree.fromstring(content)
- mathml_namespace = "http://www.w3.org/1998/Math/MathML"
- mathml_blocks = xml.xpath(
+ math_blocks = xml.xpath(
'//m:math[not(/m:annotation-xml[@encoding="image/svg+xml"])]',
- namespaces={'m': mathml_namespace})
- for mathml_block in mathml_blocks:
+ namespaces=NSMAP)
+ for math_block in math_blocks:
# Submit the MathML block to the SVG generation service.
- payload = {'MathML': etree.tostring(mathml_block)}
+ payload = {'MathML': etree.tostring(math_block)}
response = requests.post(url, data=payload)
# Inject the SVG into the MathML as an annotation
# only if the resposne was good, otherwise skip over it.
- semantic_block = mathml_block.getchildren()[0]
if response.status_code == 200:
+ semantics_wrapper = _find_or_create_semantics_block(math_block)
svg = response.text
content_type = response.headers['content-type']
# Insert the svg into the content
annotation = etree.SubElement(
- semantic_block,
- '{{{}}}annotation-xml'.format(mathml_namespace))
+ semantics_wrapper,
+ '{{{}}}annotation-xml'.format(MATHML_NAMESPACE))
annotation.set('encoding', content_type)
annotation.append(etree.fromstring(svg))
modified_content = etree.tostring(xml)
diff --git a/cnxpublishing/tests/test_models.py b/cnxpublishing/tests/test_models.py
index 3faaa4f4..f6c32532 100644
--- a/cnxpublishing/tests/test_models.py
+++ b/cnxpublishing/tests/test_models.py
@@ -60,3 +60,20 @@ def test_mathml2svg(self):
expected = """