Brings the share build up to date with the main project: QTI .zip export and optional direct Canvas API push, plus the Canvas settings card. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
56 lines
2.9 KiB
JavaScript
56 lines
2.9 KiB
JavaScript
// lib/canvas/manifest.js — the two wrapper files that make a folder of QTI XML into a
|
|
// Canvas-importable package: imsmanifest.xml (IMS Content Packaging) and the Canvas
|
|
// proprietary assessment_meta.xml (quiz-level settings).
|
|
import { xmlEsc } from "./qti";
|
|
|
|
// Canvas quiz-level settings. `title` is the only thing Canvas truly needs; everything
|
|
// else has a sensible Canvas default if omitted. We emit the fields the user can set.
|
|
export function renderAssessmentMeta(ir, assessmentIdent) {
|
|
const q = ir.quiz;
|
|
const lines = [];
|
|
const tag = (name, val) => lines.push(`<${name}>${xmlEsc(String(val))}</${name}>`);
|
|
const bool = (name, val) => tag(name, val ? "true" : "false");
|
|
const opt = (name, val) => { if (val !== "" && val != null) tag(name, val); };
|
|
|
|
tag("title", q.title);
|
|
tag("description", q.description || "");
|
|
tag("quiz_type", q.quizType);
|
|
tag("points_possible", q.pointsPossible);
|
|
opt("time_limit", q.timeLimit);
|
|
tag("allowed_attempts", q.allowedAttempts);
|
|
tag("scoring_policy", q.scoringPolicy);
|
|
bool("shuffle_answers", q.shuffleAnswers);
|
|
bool("show_correct_answers", q.showCorrectAnswers);
|
|
bool("one_question_at_a_time", q.oneQuestionAtATime);
|
|
bool("cant_go_back", q.cantGoBack);
|
|
opt("access_code", q.accessCode);
|
|
opt("due_at", q.dueAt);
|
|
opt("unlock_at", q.unlockAt);
|
|
opt("lock_at", q.lockAt);
|
|
|
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
<quiz identifier="${xmlEsc(assessmentIdent)}" xmlns="http://canvas.instructure.com/xsd/cccv1p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://canvas.instructure.com/xsd/cccv1p0 https://canvas.instructure.com/xsd/cccv1p0.xsd">
|
|
${lines.join("\n")}
|
|
</quiz>`;
|
|
}
|
|
|
|
export function renderManifest(assessmentIdent, manifestIdent) {
|
|
const assessmentHref = `${assessmentIdent}/${assessmentIdent}.xml`;
|
|
const metaHref = `${assessmentIdent}/assessment_meta.xml`;
|
|
const depIdent = `${assessmentIdent}_dependency`;
|
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
<manifest identifier="${xmlEsc(manifestIdent)}" xmlns="http://www.imsglobal.org/xsd/imsccv1p1/imscp_v1p1" xmlns:lom="http://ltsc.ieee.org/xsd/imsccv1p1/LOM/resource" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsccv1p1/imscp_v1p1 http://www.imsglobal.org/profile/cc/ccv1p1/ccv1p1_imscp_v1p2_v1p0.xsd">
|
|
<metadata><schema>IMS Content</schema><schemaversion>1.1.3</schemaversion></metadata>
|
|
<organizations/>
|
|
<resources>
|
|
<resource identifier="${xmlEsc(assessmentIdent)}" type="imsqti_xmlv1p2/imscc_xmlv1p1/assessment" href="${xmlEsc(assessmentHref)}">
|
|
<file href="${xmlEsc(assessmentHref)}"/>
|
|
<dependency identifierref="${xmlEsc(depIdent)}"/>
|
|
</resource>
|
|
<resource identifier="${xmlEsc(depIdent)}" type="associatedcontent/imscc_xmlv1p1/learning-application-resource" href="${xmlEsc(metaHref)}">
|
|
<file href="${xmlEsc(metaHref)}"/>
|
|
</resource>
|
|
</resources>
|
|
</manifest>`;
|
|
}
|