@timeback/core 0.2.0 → 0.2.1-beta.20260313210405
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/qti.d.ts +11 -0
- package/dist/qti.d.ts.map +1 -0
- package/dist/qti.js +126 -0
- package/package.json +5 -1
package/dist/qti.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QTI XML parsing utilities, re-exported from `@timeback/qti/parse`.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import { parseQtiXml, extractPrompt } from '@timeback/core/qti'
|
|
7
|
+
* ```
|
|
8
|
+
*/
|
|
9
|
+
export { extractChoices, extractCorrectResponse, extractFeedback, extractInteractionAttributes, extractModalFeedback, extractPrompt, extractResponseDeclaration, parseQtiXml, } from '@timeback/qti/parse';
|
|
10
|
+
export type { ParsedQtiItem, QtiChoice, QtiInlineFeedback, QtiInteractionAttributes, QtiModalFeedback, QtiResponseDeclaration, } from '@timeback/qti/parse';
|
|
11
|
+
//# sourceMappingURL=qti.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qti.d.ts","sourceRoot":"","sources":["../src/qti.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACN,cAAc,EACd,sBAAsB,EACtB,eAAe,EACf,4BAA4B,EAC5B,oBAAoB,EACpB,aAAa,EACb,0BAA0B,EAC1B,WAAW,GACX,MAAM,qBAAqB,CAAA;AAE5B,YAAY,EACX,aAAa,EACb,SAAS,EACT,iBAAiB,EACjB,wBAAwB,EACxB,gBAAgB,EAChB,sBAAsB,GACtB,MAAM,qBAAqB,CAAA"}
|
package/dist/qti.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import"./chunk-3j7jywnx.js";
|
|
2
|
+
|
|
3
|
+
// ../qti/src/parse.ts
|
|
4
|
+
function extractPrompt(xml) {
|
|
5
|
+
if (!xml)
|
|
6
|
+
return "";
|
|
7
|
+
const match = xml.match(/<qti-prompt[^>]*>([\s\S]*?)<\/qti-prompt>/i);
|
|
8
|
+
return match?.[1]?.trim() ?? "";
|
|
9
|
+
}
|
|
10
|
+
function extractChoices(xml) {
|
|
11
|
+
if (!xml)
|
|
12
|
+
return [];
|
|
13
|
+
const choices = [];
|
|
14
|
+
const regex = /<qti-simple-choice[^>]*identifier="([^"]+)"[^>]*>([\s\S]*?)<\/qti-simple-choice>/gi;
|
|
15
|
+
let match;
|
|
16
|
+
while ((match = regex.exec(xml)) !== null) {
|
|
17
|
+
let text = match[2] ?? "";
|
|
18
|
+
text = text.replace(/<qti-feedback-inline[\s\S]*?<\/qti-feedback-inline>/gi, "").trim();
|
|
19
|
+
choices.push({ identifier: match[1] ?? "", text });
|
|
20
|
+
}
|
|
21
|
+
return choices;
|
|
22
|
+
}
|
|
23
|
+
function extractCorrectResponse(xml) {
|
|
24
|
+
if (!xml)
|
|
25
|
+
return null;
|
|
26
|
+
const match = xml.match(/<qti-correct-response>\s*<qti-value>([^<]+)<\/qti-value>/i);
|
|
27
|
+
return match?.[1]?.trim() ?? null;
|
|
28
|
+
}
|
|
29
|
+
function extractFeedback(xml) {
|
|
30
|
+
if (!xml)
|
|
31
|
+
return [];
|
|
32
|
+
const feedback = [];
|
|
33
|
+
const regex = /<qti-feedback-inline([^>]*)>([\s\S]*?)<\/qti-feedback-inline>/gi;
|
|
34
|
+
let match;
|
|
35
|
+
while ((match = regex.exec(xml)) !== null) {
|
|
36
|
+
const attrs = match[1] ?? "";
|
|
37
|
+
const outcomeId = attrs.match(/outcome-identifier="([^"]*)"/);
|
|
38
|
+
const id = attrs.match(/(?:^|\s)identifier="([^"]*)"/);
|
|
39
|
+
const showHide = attrs.match(/show-hide="([^"]*)"/);
|
|
40
|
+
feedback.push({
|
|
41
|
+
outcomeIdentifier: outcomeId?.[1] ?? "",
|
|
42
|
+
identifier: id?.[1] ?? "",
|
|
43
|
+
showHide: showHide?.[1] ?? "show",
|
|
44
|
+
content: (match[2] ?? "").trim()
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return feedback;
|
|
48
|
+
}
|
|
49
|
+
function extractModalFeedback(xml) {
|
|
50
|
+
if (!xml)
|
|
51
|
+
return [];
|
|
52
|
+
const modalFeedback = [];
|
|
53
|
+
const regex = /<qti-modal-feedback([^>]*)>([\s\S]*?)<\/qti-modal-feedback>/gi;
|
|
54
|
+
let match;
|
|
55
|
+
while ((match = regex.exec(xml)) !== null) {
|
|
56
|
+
const attrs = match[1] ?? "";
|
|
57
|
+
const outcomeId = attrs.match(/outcome-identifier="([^"]*)"/);
|
|
58
|
+
const id = attrs.match(/(?:^|\s)identifier="([^"]*)"/);
|
|
59
|
+
const showHide = attrs.match(/show-hide="([^"]*)"/);
|
|
60
|
+
let content = match[2] ?? "";
|
|
61
|
+
const bodyMatch = content.match(/<qti-content-body>([\s\S]*?)<\/qti-content-body>/i);
|
|
62
|
+
if (bodyMatch) {
|
|
63
|
+
content = bodyMatch[1] ?? "";
|
|
64
|
+
}
|
|
65
|
+
modalFeedback.push({
|
|
66
|
+
outcomeIdentifier: outcomeId?.[1] ?? "",
|
|
67
|
+
identifier: id?.[1] ?? "",
|
|
68
|
+
showHide: showHide?.[1] ?? "show",
|
|
69
|
+
content: content.trim()
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return modalFeedback;
|
|
73
|
+
}
|
|
74
|
+
function extractInteractionAttributes(xml) {
|
|
75
|
+
if (!xml)
|
|
76
|
+
return null;
|
|
77
|
+
const match = xml.match(/<qti-choice-interaction([^>]*)>/i);
|
|
78
|
+
if (!match)
|
|
79
|
+
return null;
|
|
80
|
+
const attrs = match[1] ?? "";
|
|
81
|
+
const responseId = attrs.match(/response-identifier="([^"]*)"/);
|
|
82
|
+
const shuffle = attrs.match(/shuffle="([^"]*)"/);
|
|
83
|
+
const maxChoices = attrs.match(/max-choices="([^"]*)"/);
|
|
84
|
+
return {
|
|
85
|
+
responseIdentifier: responseId?.[1] ?? "",
|
|
86
|
+
shuffle: shuffle?.[1]?.toLowerCase() === "true",
|
|
87
|
+
maxChoices: maxChoices?.[1] ? parseInt(maxChoices[1], 10) : 1
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function extractResponseDeclaration(xml) {
|
|
91
|
+
if (!xml)
|
|
92
|
+
return null;
|
|
93
|
+
const match = xml.match(/<qti-response-declaration([^>]*)>/i);
|
|
94
|
+
if (!match)
|
|
95
|
+
return null;
|
|
96
|
+
const attrs = match[1] ?? "";
|
|
97
|
+
const identifier = attrs.match(/identifier="([^"]*)"/);
|
|
98
|
+
const cardinality = attrs.match(/cardinality="([^"]*)"/);
|
|
99
|
+
const baseType = attrs.match(/base-type="([^"]*)"/);
|
|
100
|
+
return {
|
|
101
|
+
identifier: identifier?.[1] ?? "",
|
|
102
|
+
cardinality: cardinality?.[1] ?? "",
|
|
103
|
+
baseType: baseType?.[1] ?? null
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function parseQtiXml(xml) {
|
|
107
|
+
return {
|
|
108
|
+
prompt: extractPrompt(xml),
|
|
109
|
+
choices: extractChoices(xml),
|
|
110
|
+
correctAnswer: extractCorrectResponse(xml),
|
|
111
|
+
feedback: extractFeedback(xml),
|
|
112
|
+
modalFeedback: extractModalFeedback(xml),
|
|
113
|
+
interaction: extractInteractionAttributes(xml),
|
|
114
|
+
responseDeclaration: extractResponseDeclaration(xml)
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
export {
|
|
118
|
+
parseQtiXml,
|
|
119
|
+
extractResponseDeclaration,
|
|
120
|
+
extractPrompt,
|
|
121
|
+
extractModalFeedback,
|
|
122
|
+
extractInteractionAttributes,
|
|
123
|
+
extractFeedback,
|
|
124
|
+
extractCorrectResponse,
|
|
125
|
+
extractChoices
|
|
126
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timeback/core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1-beta.20260313210405",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
"./utils": {
|
|
19
19
|
"types": "./dist/utils.d.ts",
|
|
20
20
|
"import": "./dist/utils.js"
|
|
21
|
+
},
|
|
22
|
+
"./qti": {
|
|
23
|
+
"types": "./dist/qti.d.ts",
|
|
24
|
+
"import": "./dist/qti.js"
|
|
21
25
|
}
|
|
22
26
|
},
|
|
23
27
|
"main": "dist/index.js",
|