Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Views: 1833
Image: ubuntu2004
1
from lxml import etree
2
from lxml import html as lxml_html
3
from .xml import xsl_transform, xml_boilerplate
4
from latex2mathml.converter import convert
5
import pystache
6
import urllib
7
import json
8
9
def tex_to_mathml(tex):
10
return etree.fromstring(convert(tex))
11
12
class Exercise:
13
def __init__(self, data=None, seed=None, outcome=None):
14
self.data = data
15
self.seed = seed
16
self.outcome = outcome
17
18
def pretext_tree(self):
19
renderer = pystache.Renderer()
20
xml_string = renderer.render_path(self.outcome.template_filepath(),self.data)
21
tree = etree.fromstring(bytes(xml_string, encoding='utf-8'))
22
tree.find(".").attrib.pop("version")
23
tree.find(".").set('checkit-seed', f"{self.seed:04}")
24
tree.find(".").set('checkit-slug', str(self.outcome.slug))
25
tree.find(".").set('checkit-title', str(self.outcome.title))
26
27
#remove namespace
28
for elem in tree.getiterator():
29
if not(type(elem) == etree._Comment):
30
elem.tag = etree.QName(elem).localname
31
etree.cleanup_namespaces(tree)
32
33
return tree
34
35
def pretext(self):
36
return str(etree.tostring(self.pretext_tree(), pretty_print=True), encoding="UTF-8")
37
38
def html_tree(self):
39
transform = xsl_transform("html")
40
tree = transform(self.pretext_tree()).getroot()
41
return tree
42
43
def html(self):
44
return str(etree.tostring(self.html_tree(),pretty_print=True), 'utf-8')
45
46
def latex(self):
47
transform = xsl_transform("latex")
48
return str(transform(self.pretext_tree()))
49
50
def canvas_tree(self):
51
transform = xsl_transform("canvas")
52
tree = transform(self.pretext_tree()).getroot()
53
for mattextxml in tree.xpath("//mattextxml"):
54
for img in mattextxml.xpath("//img[@data-equation-content]"):
55
tex = img.get("data-equation-content")
56
src = "https://canvas.instructure.com/equation_images/"+ \
57
urllib.parse.quote(urllib.parse.quote(tex))
58
img.set("src",src)
59
mattext = etree.Element("mattext")
60
mattext.attrib['texttype'] = 'text/html'
61
mattext.text = lxml_html.tostring(lxml_html.fromstring(etree.tostring(mattextxml.find("*"),pretty_print=True)),pretty_print=True)
62
mattextxml.addnext(mattext)
63
return tree
64
65
def brightspace_tree(self):
66
item = xml_boilerplate("brightspace_questiondb_exercise").getroot()
67
transform = xsl_transform("brightspace")
68
statement_tree = transform(self.pretext_tree().find("statement")).getroot()
69
answer_tree = transform(self.pretext_tree().find("answer")).getroot()
70
for tree in [statement_tree,answer_tree]:
71
for elem in tree.iterfind(".//mathml"):
72
tex = elem.get("latex")
73
mathml = tex_to_mathml(tex)
74
elem.addnext(mathml)
75
# parent = elem.getparent()
76
# index = parent.index(elem)+1
77
# parent.insert(index,mathml)
78
del elem
79
statement_encoded = lxml_html.tostring(lxml_html.fromstring(etree.tostring(statement_tree,pretty_print=True)),pretty_print=True)
80
item.find("presentation/flow/material/mattext").text = statement_encoded
81
answer_encoded = lxml_html.tostring(lxml_html.fromstring(etree.tostring(answer_tree,pretty_print=True)),pretty_print=True)
82
item.find("answer_key//mattext").text = answer_encoded
83
return item
84
85
def moodle_xmle(self):
86
transform = xsl_transform("html")
87
root = etree.Element("question")
88
root.set("type","essay")
89
name = etree.SubElement(root,"name")
90
name_text = etree.SubElement(name,"text")
91
name_text.text = f"{self.outcome.slug} | {self.outcome.title} | ver. {self.seed}"
92
statement = etree.SubElement(root,"questiontext")
93
statement.set("format","html")
94
statement_text = etree.SubElement(statement,"text")
95
statement_text.text = etree.tostring(transform(self.pretext_tree().find("statement")))
96
answer = etree.SubElement(root,"generalfeedback")
97
answer_text = etree.SubElement(answer,"text")
98
answer_text.text = etree.tostring(transform(self.pretext_tree().find("answer")))
99
attachments = etree.SubElement(root,"attachments")
100
attachments.text = "1"
101
return root
102
103
def dict(self):
104
return {
105
"seed": self.seed,
106
"pretext": self.pretext(),
107
"html": self.html(),
108
"tex": self.latex(),
109
}
110
111
def print_preview(self):
112
print("Data JSON")
113
print("-----------")
114
print(json.dumps(self.data, indent=2))
115
print()
116
print("PreTeXt source")
117
print("------------")
118
print(self.pretext())
119
print()
120
print("HTML source")
121
print("-----------")
122
print(self.html())
123
print()
124
print("LaTeX source")
125
print("------------")
126
print(self.latex())
127
128