Published
Edited
Sep 17, 2021
Fork of Moodle XML
Insert cell
Insert cell
{
// A Função MoodleXML(cat, qg, n=10) produz um arquivo no formato Moodle XML
// a partir de uma função geradora de questões qg. São geradas n questões
// na categoria cat. A função qg recebe um inteiro i entre 1 e n e deve
// retornar um objeto q com dois campos: q.text, o texto da questão,
// e q.answer. Se q.answer for um array, a questão é de múltipla escolha,
// com a primeira resposta sendo a resposta correta,
// se q.answer for um número, a questão é numérica, se q.answer for uma
// string, a questão é de tipo 'Resposta curta' e se q.answer for undefined, a questão é do tipo ensaio.
const cat = "Teste";
let xml = MoodleXML(cat, (i) => {
const q = {};
q.text = raw`Quanto é \( ${i}+${i} \) ?`;
q.answer = i + i;
return q;
});
return downloadButton(`${cat}.xml`, xml);
}
Insert cell
function MoodleXML(cat, qg, n = 10) {
let xml = `
<?xml version="1.0" ?>
<quiz>
<question type="category">
<category>
<text>$course$/${cat}</text>
</category></question>
`;
for (let i = 1; i <= n; ++i) {
let q = qg(i);
if (Array.isArray(q.answer)) {
// Multiple
xml =
xml +
`<question type="multichoice">
<name><text>${cat + '#' + i}</text></name>
<questiontext format="html"><text><![CDATA[${q.text}]]></text></questiontext>`;
for (let j = 0; j < q.answer.length; ++j) {
xml =
xml +
`<answer fraction="${j == 0 ? '100' : '0'}">
<text><![CDATA[${q.answer[j]}]]></text>
</answer>`;
}
xml =
xml +
` <shuffleanswers>1</shuffleanswers>
<single>true</single>
<answernumbering>abc</answernumbering>`;
} else if (q.answer === undefined) {
xml =
xml +
`<question type="essay">
<name>
<text>${cat + '#' + i}</text>
</name>
<questiontext format="html">
<text><![CDATA[<p>${q.text}</p>]]></text>
</questiontext>
<defaultgrade>1.0</defaultgrade>
<generalfeedback format="html"><text/></generalfeedback>
<penalty>0.1000000</penalty>
<hidden>0</hidden>
<responserequired>1</responserequired>
<responseformat>noinline</responseformat>
<responsefieldlines>15</responsefieldlines>
<attachments>1</attachments>
<attachmentsrequired>1</attachmentsrequired>
<graderinfo format="html"><text/></graderinfo>
<responsetemplate format="html"><text/></responsetemplate>
`;
} else if (typeof q.answer == 'number') {
// Numeric
xml =
xml +
`<question type="numerical">
<name><text>${cat + '#' + i}</text></name>
<questiontext format="html"><text><![CDATA[${q.text}]]></text></questiontext>`;
xml =
xml +
`<answer fraction="100">
<text><![CDATA[${q.answer}]]></text>
</answer>`;
} else {
// Short
xml =
xml +
`<question type="shortanswer">
<name><text>${cat + '#' + i}</text></name>
<questiontext format="html"><text><![CDATA[${q.text}]]></text></questiontext>`;
xml =
xml +
`<answer fraction="100">
<text><![CDATA[${q.answer}]]></text>
</answer>`;
}
xml = xml + `</question>`;
}
xml = xml + `</quiz>`;
return xml;
}
Insert cell
function downloadButton(filename, str, type = "text/xml") {
const strBlob = new Blob([str], { type: type });
const size = (strBlob.size / 1024).toFixed(0);

const button = DOM.download(
strBlob,
filename,
`Download ${filename} (~${size} KB)`
);
return button;
}
Insert cell
function raw() {
var string = String.raw.apply(String, arguments);
return string;
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more