Skip to content
Snippets Groups Projects
Commit 26be2f42 authored by Mathieu Loiseau's avatar Mathieu Loiseau
Browse files

listings

parent 54eef09c
No related branches found
No related tags found
No related merge requests found
......@@ -10,6 +10,7 @@ class Quizz:
self.file_name = file_name
self.tree = ET.parse(self.file_name)
self.questions = {}
self.categories = {}
self.folder = target_folder
self.parse()
......@@ -19,19 +20,21 @@ class Quizz:
def create_question(self, q, c):
if c not in self.questions.keys():
self.questions[c] = []
self.categories[c] = f"c{len(self.categories)}"
if q.attrib['type'] == "multichoice":
newQ = MCQ(q,c,len(self.questions[c]),self.folder)
newQ = MCQ(q,self.categories[c],len(self.questions[c]),self.folder)
elif q.attrib['type'] == "shortanswer":
newQ = ShortAnswer(q,c,len(self.questions[c]),self.folder)
newQ = ShortAnswer(q,self.categories[c],len(self.questions[c]),self.folder)
elif q.attrib['type'] == "truefalse":
newQ = TF(q,c,len(self.questions[c]),self.folder)
newQ = TF(q,self.categories[c],len(self.questions[c]),self.folder)
elif q.attrib['type'] == "matching":
newQ = Question(q,c,len(self.questions[c]),self.folder)
newQ = Question(q,self.categories[c],len(self.questions[c]),self.folder)#non traité
elif q.attrib['type'] == "ddimageortext":
newQ = Question(q,c,len(self.questions[c]),self.folder)
newQ = Question(q,self.categories[c],len(self.questions[c]),self.folder)#non traité
else:
raise f"{q.attrib['type']} is not expected"
self.questions[c].append(newQ)
if newQ.__class__.__name__ != "Question":
self.questions[c].append(newQ)
def parse(self):
questions = self.tree.findall("question")
......@@ -43,10 +46,16 @@ class Quizz:
def __str__(self):
res = ""
for c_q in self.questions.values():
digest ="%%%Exemple d'examen\n\t\t%\\cleargroup{exam}\n"
for c,c_q in self.questions.items():
tmp = "\t\t%\\shufflegroup{"+self.categories[c]+"}%("+c+"):"
count = 0
for q in c_q:
res += str(q)
return res
count += 1
if count > 0:
digest += f"{tmp}{count} questions\n\t\t%\\copygroup[{int(count / 2)}]" + "{" + self.categories[c] + "}" + "{exam}\n"
return digest+"\t\t%\shufflegroup{exam}\n\t\t%\insertgroup{exam}\n\n"+res
def save(self):
name = self.file_name[self.file_name.rfind('/')+1:self.file_name.rfind('.')]
......@@ -56,9 +65,9 @@ class Quizz:
class Question:
def __init__(self,xmlQ,c,n,f):
self.folder = f
self.q = strip_tags(mlang_2_multiling(xmlQ.find("questiontext/text").text), self.folder)
self.id = mlang_2_multiling(xmlQ.find("name/text").text,"en")+f".{n}"
self.q = strip_tags(mlang_2_multiling(xmlQ.find("questiontext/text").text), self.folder,self.id)
self.category = c
self.id = mlang_2_multiling(xmlQ.find("name/text").text,"en")+f":{n}"
self.env = "todo:"+xmlQ.attrib["type"]
self.max = float(xmlQ.find("defaultgrade").text)
self.parseImages(xmlQ.findall(".//file"))
......@@ -114,8 +123,8 @@ class MCQ(Question):
for a in xmlQ.findall("answer"):
fb = a.find("feedback/text").text
if fb != None:
fb = strip_tags(mlang_2_multiling(fb), self.folder)
self.choices.append(Answer(strip_tags(mlang_2_multiling(a.find("text").text), self.folder), a.attrib['fraction'], self.max, fb))
fb = strip_tags(mlang_2_multiling(fb), self.folder, self.id)
self.choices.append(Answer(strip_tags(mlang_2_multiling(a.find("text").text), self.folder,self.id), a.attrib['fraction'], self.max, fb))
def get_choice_env(self):
if self.choice_type == MCQ.VERTICAL:
......@@ -148,7 +157,7 @@ class TF(MCQ):
for a in xmlQ.findall("answer"):
fb = a.find("feedback/text").text
if fb != None:
fb = strip_tags(mlang_2_multiling(fb), self.folder)
fb = strip_tags(mlang_2_multiling(fb), self.folder, self.id)
if a.find("text").text == "true":
self.choices.append(Answer("\\multiling{vrai}{true}", a.attrib['fraction'], self.max, fb))
else:
......@@ -170,7 +179,7 @@ class ShortAnswer(TF):
def __str__(self):
res = """\\element{"""+self.category+"""}{
\\begin{"""+self.env+"""}{"""+self.id+"""}\\nbpoints{"""+score_2_str(self.max)+"""}
"""+self.q+"\n\t\t\\AMCOpen{lineheigh=0.8cm,lines="+str(self.nb_lines)+"}{"
"""+self.q+"\n\t\t\\AMCOpen{lineheight=0.66cm,lines="+str(self.nb_lines)+"}{"
for c in self.choices:
res += "\\wrongchoice{"+score_2_str(c)+"}\\scoring{"+score_2_str(c)+"}"
res += "\\correctchoice{"+score_2_str(self.max)+"}\\scoring{"+score_2_str(self.max)+"}"
......@@ -178,7 +187,7 @@ class ShortAnswer(TF):
return res
if __name__ == "__main__":
quizz = Quizz("data/quiz-GI-4-SID-S1-top-20201204-1620_corrigé.xml", "data")
quizz = Quizz("data/SID questions.xml", "data")
#quizz = Quizz("data/quiz-GI-4.xml" , "data")
#print(quizz)
quizz.save()
#!/usr/bin/env python3
from re import compile,sub,escape
from re import compile,sub,escape,findall,DOTALL
from html import unescape
from urllib.parse import unquote
unsafe = True
def html_2_tex(text):
#https://code.activestate.com/recipes/81330-single-pass-multiple-replace/
# dict = {'&nbsp;': '~', '&gt;':'>', '&lt;': '<'}
# """ Replace in 'text' all occurences of any key in the given
# dictionary by its corresponding value. Returns the new tring."""
# # Create a regular expression from the dictionary keys
# regex = compile("(%s)" % "|".join(map(escape, dict.keys())))
#
# # For each match, look-up corresponding value in dictionary
# return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
return unescape(text)
def process_listings(txt, folder="",q="q"):
txt = txt.replace("\r\n","\n")
listings = findall(r'\<pre\>(.*)\</pre\>', txt, DOTALL)
i=0
for l in listings:
if folder != "":
folder+="/"
i+=1
filename = folder+"Images/"+q+str(i)+".txt"
f = open(filename, "w")
f.write(unescape(l))
txt = txt.replace("<pre>"+l+"</pre>","\t\t\\lstinputlisting[language=Python]{"+filename.replace(folder,"")+"}")
return txt
def remove_moodle_cdata(txt, folder):
def remove_moodle_cdata(txt, folder, q):
global unsafe
txt = process_listings(txt, folder, q)
res = sub(r'<img src="[^/]*/([^"]*)" (alt="([^"]*)")?[^>]*>', r"""\\begin{figure}[h!]
\\begin{center}
\\includegraphics[width=0.8\\linewidth]{$$$$folder$$$$/\1}
\\includegraphics[width=0.8\\linewidth]{Images/\1}
\\end{center}
\\caption{\3}
\\end{figure}
""",txt).replace("<![CDATA[","").replace("]]>","").replace("$$$$folder$$$$", folder+"/Images").replace("<strong>","\\emph{").replace("</strong>","}").replace("<pre>","\\begin{lstlisting}[language=Python]\n").replace("</pre>","\\end{lstlisting}\n")
""",txt).replace("<![CDATA[","").replace("]]>","").replace("<strong>","\\emph{").replace("</strong>","}")
if unsafe:
res = res.replace('<span style="font:monospace">',"\lstinline[language=python]|").replace('<span style="font-family:monospace">',"\lstinline[language=python]|").replace("</span>","|")
res = res.replace('<span style="font:monospace">',"\lstinline[language=python]|").replace('<span style="font-family:monospace">',"\lstinline[language=python]|").replace('<span style="font-family=monospace">',"\lstinline[language=python]|").replace("</span>","|")
return res
def strip_tags(txt, folder):
return html_2_tex(sub(compile('<.*?>'), '',remove_moodle_cdata(unquote(txt), folder)))
def strip_tags(txt, folder,q="q"):
return unescape(sub(compile('<.*?>'), '',remove_moodle_cdata(unquote(txt.replace("&nbsp;","~")),folder,q)))
def mlang_2_multiling(txt, which = "both"):
if which == "fr":
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment