Skip to content

Commit

Permalink
Create the mathml semantics block if it doesn't exist.
Browse files Browse the repository at this point in the history
  • Loading branch information
mmulich committed Sep 1, 2015
1 parent 499703c commit e133581
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 8 deletions.
39 changes: 31 additions & 8 deletions cnxpublishing/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
17 changes: 17 additions & 0 deletions cnxpublishing/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,20 @@ def test_mathml2svg(self):
expected = """<annotation-xml xmlns="http://www.w3.org/1998/Math/MathML" encoding="image/svg+xml"><svg>mocked</svg></annotation-xml>"""

self.assertEqual(etree.tostring(annotation), expected)

def test_missing_semantics_wrapper(self):
content = """\
<div class="equation">
<math xmlns="http://www.w3.org/1998/Math/MathML"><mrow> <mi>x</mi> <mo>=</mo> <mfrac> <mrow> <mo>&#8722;<!-- &#8722; --></mo> <mi>b</mi> <mo>&#177;<!-- &#177; --></mo> <msqrt> <msup> <mi>b</mi> <mn>2</mn> </msup> <mo>&#8722;<!-- &#8722; --></mo> <mn>4</mn> <mi>a</mi> <mi>c</mi> </msqrt> </mrow> <mrow> <mn>2</mn> <mi>a</mi> </mrow> </mfrac> </mrow></math>
</div>"""

# Call the target function.
result = self.target(content)

elms = etree.fromstring(result)
annotation = elms.xpath(
'/div/m:math/m:semantics/m:annotation-xml[@encoding="image/svg+xml"]',
namespaces={'m': "http://www.w3.org/1998/Math/MathML"})[0]
expected = """<annotation-xml xmlns="http://www.w3.org/1998/Math/MathML" encoding="image/svg+xml"><svg>mocked</svg></annotation-xml>"""

self.assertEqual(etree.tostring(annotation), expected)

0 comments on commit e133581

Please sign in to comment.