lens-content-processor 0.41.0 → 0.42.0
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/content-schema.js +6 -0
- package/dist/content-schema.js.map +1 -1
- package/dist/flattener/index.js +71 -0
- package/dist/flattener/index.js.map +1 -1
- package/dist/index.d.ts +17 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/parser/lens.d.ts +6 -1
- package/dist/parser/lens.js +56 -1
- package/dist/parser/lens.js.map +1 -1
- package/dist/parser/sections.js +1 -0
- package/dist/parser/sections.js.map +1 -1
- package/dist/parser/widget.d.ts +25 -0
- package/dist/parser/widget.js +367 -0
- package/dist/parser/widget.js.map +1 -0
- package/dist/validator/criticmarkup.js +1 -0
- package/dist/validator/criticmarkup.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
// src/parser/widget.ts
|
|
2
|
+
//
|
|
3
|
+
// A widget is a self-contained interactive HTML page authored in the
|
|
4
|
+
// `widgets/` folder. The file is Markdown only by extension: YAML frontmatter
|
|
5
|
+
// carries the metadata, the body is the full HTML document that the platform
|
|
6
|
+
// renders for learners inside a sandboxed iframe. Keeping the `.md` extension
|
|
7
|
+
// means widgets flow through the editor, relay-git-sync, promotion and CI
|
|
8
|
+
// exactly like every other content file; only this parser treats the body
|
|
9
|
+
// as HTML.
|
|
10
|
+
import { parse as parseHtml, defaultTreeAdapter, Tokenizer, TokenizerMode, } from "parse5";
|
|
11
|
+
import { parseFrontmatter } from "./frontmatter.js";
|
|
12
|
+
import { validateFrontmatter } from "../validator/validate-frontmatter.js";
|
|
13
|
+
import { stripAuthoringMarkup } from "../authoring-markup.js";
|
|
14
|
+
/** Widgets are inlined into module JSON; above this the page payload suffers. */
|
|
15
|
+
export const MAX_WIDGET_HTML_BYTES = 400 * 1024;
|
|
16
|
+
// parse5 reports every HTML5 parse error, including ones browsers recover from
|
|
17
|
+
// identically to the author's intent. These never change what renders.
|
|
18
|
+
const BENIGN_PARSE_ERRORS = new Set([
|
|
19
|
+
"missing-doctype",
|
|
20
|
+
"open-elements-left-after-eof",
|
|
21
|
+
"duplicate-attribute",
|
|
22
|
+
]);
|
|
23
|
+
// Elements whose text is not learner-visible prose.
|
|
24
|
+
const SKIPPED_TEXT_ELEMENTS = new Set([
|
|
25
|
+
"script",
|
|
26
|
+
"style",
|
|
27
|
+
"svg",
|
|
28
|
+
"noscript",
|
|
29
|
+
"template",
|
|
30
|
+
"head",
|
|
31
|
+
]);
|
|
32
|
+
const BLOCK_ELEMENTS = new Set([
|
|
33
|
+
"p",
|
|
34
|
+
"div",
|
|
35
|
+
"section",
|
|
36
|
+
"article",
|
|
37
|
+
"header",
|
|
38
|
+
"footer",
|
|
39
|
+
"main",
|
|
40
|
+
"aside",
|
|
41
|
+
"nav",
|
|
42
|
+
"h1",
|
|
43
|
+
"h2",
|
|
44
|
+
"h3",
|
|
45
|
+
"h4",
|
|
46
|
+
"h5",
|
|
47
|
+
"h6",
|
|
48
|
+
"li",
|
|
49
|
+
"ul",
|
|
50
|
+
"ol",
|
|
51
|
+
"tr",
|
|
52
|
+
"td",
|
|
53
|
+
"th",
|
|
54
|
+
"table",
|
|
55
|
+
"blockquote",
|
|
56
|
+
"pre",
|
|
57
|
+
"figure",
|
|
58
|
+
"figcaption",
|
|
59
|
+
"button",
|
|
60
|
+
"label",
|
|
61
|
+
"br",
|
|
62
|
+
"hr",
|
|
63
|
+
"summary",
|
|
64
|
+
"details",
|
|
65
|
+
"dt",
|
|
66
|
+
"dd",
|
|
67
|
+
]);
|
|
68
|
+
export function isWidgetPath(path) {
|
|
69
|
+
return path.startsWith("widgets/") || path.includes("/widgets/");
|
|
70
|
+
}
|
|
71
|
+
export function parseWidget(content, file) {
|
|
72
|
+
const errors = [];
|
|
73
|
+
const fm = parseFrontmatter(stripAuthoringMarkup(content), file);
|
|
74
|
+
if (fm.error) {
|
|
75
|
+
errors.push(fm.error);
|
|
76
|
+
return { widget: null, errors };
|
|
77
|
+
}
|
|
78
|
+
errors.push(...validateFrontmatter(fm.frontmatter, "widget", file));
|
|
79
|
+
const html = fm.body.trim();
|
|
80
|
+
if (!html) {
|
|
81
|
+
errors.push({
|
|
82
|
+
file,
|
|
83
|
+
line: fm.bodyStartLine,
|
|
84
|
+
message: "Widget body is empty",
|
|
85
|
+
suggestion: "Write the widget's HTML document below the frontmatter (a complete <!doctype html> page with its own CSS and JS)",
|
|
86
|
+
severity: "error",
|
|
87
|
+
});
|
|
88
|
+
return { widget: null, errors };
|
|
89
|
+
}
|
|
90
|
+
if (Buffer.byteLength(html, "utf8") > MAX_WIDGET_HTML_BYTES) {
|
|
91
|
+
errors.push({
|
|
92
|
+
file,
|
|
93
|
+
line: fm.bodyStartLine,
|
|
94
|
+
message: `Widget HTML is larger than ${MAX_WIDGET_HTML_BYTES / 1024}KB`,
|
|
95
|
+
suggestion: "Widgets are inlined into every module that uses them; move large data or media to an external URL",
|
|
96
|
+
severity: "error",
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
const { document, parseErrors } = parseHtmlDocument(html);
|
|
100
|
+
// Tag-balance findings first: they name the tag and line an author can act
|
|
101
|
+
// on, where a tokenizer error code often only says where parsing went wrong.
|
|
102
|
+
const htmlErrors = [...checkTagBalance(html), ...parseErrors];
|
|
103
|
+
for (const err of htmlErrors.slice(0, MAX_REPORTED_HTML_ERRORS)) {
|
|
104
|
+
errors.push({
|
|
105
|
+
file,
|
|
106
|
+
line: fm.bodyStartLine + err.line - 1,
|
|
107
|
+
message: `Invalid HTML: ${err.code}`,
|
|
108
|
+
suggestion: "Fix the markup so the page parses cleanly; a broken widget shows learners a 'could not be loaded' notice",
|
|
109
|
+
severity: "error",
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
if (htmlErrors.length > MAX_REPORTED_HTML_ERRORS) {
|
|
113
|
+
errors.push({
|
|
114
|
+
file,
|
|
115
|
+
line: fm.bodyStartLine,
|
|
116
|
+
message: `Invalid HTML: ${htmlErrors.length - MAX_REPORTED_HTML_ERRORS} more problem(s) not shown`,
|
|
117
|
+
suggestion: "Fix the ones above and re-validate",
|
|
118
|
+
severity: "error",
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
const height = frontmatterString(fm.frontmatter.height);
|
|
122
|
+
if (height !== undefined && !isValidHeight(height)) {
|
|
123
|
+
errors.push({
|
|
124
|
+
file,
|
|
125
|
+
line: 2,
|
|
126
|
+
message: `Invalid widget height: ${height}`,
|
|
127
|
+
suggestion: 'Use "auto" (default) or a CSS length such as 480px',
|
|
128
|
+
severity: "error",
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
const widget = {
|
|
132
|
+
html,
|
|
133
|
+
text: extractVisibleText(document),
|
|
134
|
+
};
|
|
135
|
+
const title = frontmatterString(fm.frontmatter.title);
|
|
136
|
+
if (title)
|
|
137
|
+
widget.title = title;
|
|
138
|
+
const summary = frontmatterString(fm.frontmatter.summary_for_tutor);
|
|
139
|
+
if (summary)
|
|
140
|
+
widget.summaryForTutor = summary;
|
|
141
|
+
if (!widget.text && !summary) {
|
|
142
|
+
// A widget that builds its UI in JavaScript has no static text to give
|
|
143
|
+
// the tutor; the summary is then the tutor's only view of it.
|
|
144
|
+
errors.push({
|
|
145
|
+
file,
|
|
146
|
+
line: 2,
|
|
147
|
+
message: "Widget has no visible text in its HTML and no summary_for_tutor; the tutor cannot see what the learner does here",
|
|
148
|
+
suggestion: "Add summary_for_tutor to the frontmatter describing what the widget shows and what the learner does with it",
|
|
149
|
+
severity: "warning",
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
if (height && isValidHeight(height))
|
|
153
|
+
widget.height = height;
|
|
154
|
+
return { widget, errors };
|
|
155
|
+
}
|
|
156
|
+
function frontmatterString(value) {
|
|
157
|
+
if (value === undefined || value === null)
|
|
158
|
+
return undefined;
|
|
159
|
+
const str = String(value).trim();
|
|
160
|
+
return str === "" ? undefined : str;
|
|
161
|
+
}
|
|
162
|
+
function isValidHeight(height) {
|
|
163
|
+
return height === "auto" || /^\d+(\.\d+)?(px|rem|em|vh)$/.test(height);
|
|
164
|
+
}
|
|
165
|
+
const MAX_REPORTED_HTML_ERRORS = 5;
|
|
166
|
+
// Browsers (and parse5) silently recover from stray or mis-nested end tags,
|
|
167
|
+
// so the HTML5 parser reports nothing for the mistakes authors actually make.
|
|
168
|
+
// This pass walks the token stream with an open-element stack for the tags
|
|
169
|
+
// that have no implicit-close rules and reports what the recovery hides.
|
|
170
|
+
const STRICT_TAGS = new Set([
|
|
171
|
+
"div",
|
|
172
|
+
"section",
|
|
173
|
+
"article",
|
|
174
|
+
"main",
|
|
175
|
+
"header",
|
|
176
|
+
"footer",
|
|
177
|
+
"aside",
|
|
178
|
+
"nav",
|
|
179
|
+
"span",
|
|
180
|
+
"a",
|
|
181
|
+
"button",
|
|
182
|
+
"label",
|
|
183
|
+
"table",
|
|
184
|
+
"ul",
|
|
185
|
+
"ol",
|
|
186
|
+
"form",
|
|
187
|
+
"select",
|
|
188
|
+
"textarea",
|
|
189
|
+
"details",
|
|
190
|
+
"summary",
|
|
191
|
+
"figure",
|
|
192
|
+
"figcaption",
|
|
193
|
+
"blockquote",
|
|
194
|
+
"pre",
|
|
195
|
+
"code",
|
|
196
|
+
"em",
|
|
197
|
+
"strong",
|
|
198
|
+
"b",
|
|
199
|
+
"i",
|
|
200
|
+
"small",
|
|
201
|
+
"sup",
|
|
202
|
+
"sub",
|
|
203
|
+
"svg",
|
|
204
|
+
"h1",
|
|
205
|
+
"h2",
|
|
206
|
+
"h3",
|
|
207
|
+
"h4",
|
|
208
|
+
"h5",
|
|
209
|
+
"h6",
|
|
210
|
+
"script",
|
|
211
|
+
"style",
|
|
212
|
+
"template",
|
|
213
|
+
"iframe",
|
|
214
|
+
"canvas",
|
|
215
|
+
"video",
|
|
216
|
+
"audio",
|
|
217
|
+
]);
|
|
218
|
+
const VOID_TAGS = new Set([
|
|
219
|
+
"area",
|
|
220
|
+
"base",
|
|
221
|
+
"br",
|
|
222
|
+
"col",
|
|
223
|
+
"embed",
|
|
224
|
+
"hr",
|
|
225
|
+
"img",
|
|
226
|
+
"input",
|
|
227
|
+
"link",
|
|
228
|
+
"meta",
|
|
229
|
+
"source",
|
|
230
|
+
"track",
|
|
231
|
+
"wbr",
|
|
232
|
+
]);
|
|
233
|
+
// Unclosed at EOF, these swallow the rest of the document.
|
|
234
|
+
const MUST_CLOSE_TAGS = new Set(["script", "style", "template", "textarea"]);
|
|
235
|
+
const RAWTEXT_TAGS = new Set(["style", "xmp", "iframe", "noembed", "noframes"]);
|
|
236
|
+
const RCDATA_TAGS = new Set(["textarea", "title"]);
|
|
237
|
+
function checkTagBalance(html) {
|
|
238
|
+
const errors = [];
|
|
239
|
+
// Open strict elements (and every element inside <svg>, where nesting is XML-strict).
|
|
240
|
+
const stack = [];
|
|
241
|
+
let svgDepth = 0;
|
|
242
|
+
const line = (token) => token.location?.startLine ?? 1;
|
|
243
|
+
const tokenizer = new Tokenizer({ sourceCodeLocationInfo: true }, {
|
|
244
|
+
onStartTag(token) {
|
|
245
|
+
const tag = token.tagName;
|
|
246
|
+
if (tag === "script")
|
|
247
|
+
tokenizer.state = TokenizerMode.SCRIPT_DATA;
|
|
248
|
+
else if (RAWTEXT_TAGS.has(tag))
|
|
249
|
+
tokenizer.state = TokenizerMode.RAWTEXT;
|
|
250
|
+
else if (RCDATA_TAGS.has(tag))
|
|
251
|
+
tokenizer.state = TokenizerMode.RCDATA;
|
|
252
|
+
if (svgDepth > 0 || tag === "svg") {
|
|
253
|
+
if (tag === "svg")
|
|
254
|
+
svgDepth += 1;
|
|
255
|
+
if (token.selfClosing) {
|
|
256
|
+
if (tag === "svg")
|
|
257
|
+
svgDepth -= 1;
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
stack.push({ tag, line: line(token) });
|
|
261
|
+
}
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
if (VOID_TAGS.has(tag))
|
|
265
|
+
return;
|
|
266
|
+
if (token.selfClosing) {
|
|
267
|
+
errors.push({
|
|
268
|
+
code: `self-closing <${tag}/> is not allowed in HTML (the element stays open)`,
|
|
269
|
+
line: line(token),
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
if (STRICT_TAGS.has(tag))
|
|
273
|
+
stack.push({ tag, line: line(token) });
|
|
274
|
+
},
|
|
275
|
+
onEndTag(token) {
|
|
276
|
+
const tag = token.tagName;
|
|
277
|
+
if (svgDepth === 0 && !STRICT_TAGS.has(tag))
|
|
278
|
+
return;
|
|
279
|
+
const index = stack.map((e) => e.tag).lastIndexOf(tag);
|
|
280
|
+
if (index === -1) {
|
|
281
|
+
errors.push({
|
|
282
|
+
code: `stray end tag </${tag}> (no open <${tag}>)`,
|
|
283
|
+
line: line(token),
|
|
284
|
+
});
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
for (let i = stack.length - 1; i > index; i--) {
|
|
288
|
+
errors.push({
|
|
289
|
+
code: `</${tag}> closes while <${stack[i].tag}> (line ${stack[i].line}) is still open`,
|
|
290
|
+
line: line(token),
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
const closed = stack.splice(index);
|
|
294
|
+
svgDepth -= closed.filter((e) => e.tag === "svg").length;
|
|
295
|
+
},
|
|
296
|
+
onEof() {
|
|
297
|
+
for (const open of stack) {
|
|
298
|
+
if (MUST_CLOSE_TAGS.has(open.tag)) {
|
|
299
|
+
errors.push({
|
|
300
|
+
code: `<${open.tag}> is never closed; everything after it is swallowed`,
|
|
301
|
+
line: open.line,
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
},
|
|
306
|
+
onComment() { },
|
|
307
|
+
onDoctype() { },
|
|
308
|
+
onCharacter() { },
|
|
309
|
+
onWhitespaceCharacter() { },
|
|
310
|
+
onNullCharacter() { },
|
|
311
|
+
onParseError() { },
|
|
312
|
+
});
|
|
313
|
+
tokenizer.write(html, true);
|
|
314
|
+
return errors;
|
|
315
|
+
}
|
|
316
|
+
function parseHtmlDocument(html) {
|
|
317
|
+
const parseErrors = [];
|
|
318
|
+
const document = parseHtml(html, {
|
|
319
|
+
sourceCodeLocationInfo: true,
|
|
320
|
+
onParseError: (err) => {
|
|
321
|
+
if (BENIGN_PARSE_ERRORS.has(err.code))
|
|
322
|
+
return;
|
|
323
|
+
parseErrors.push({ code: err.code, line: err.startLine });
|
|
324
|
+
},
|
|
325
|
+
});
|
|
326
|
+
return { document, parseErrors };
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Learner-visible text of the document, block elements separated by blank
|
|
330
|
+
* lines, whitespace collapsed. Scripts, styles and SVG geometry are left out.
|
|
331
|
+
*/
|
|
332
|
+
export function extractVisibleText(document) {
|
|
333
|
+
const parts = [];
|
|
334
|
+
const visit = (node) => {
|
|
335
|
+
if (defaultTreeAdapter.isTextNode(node)) {
|
|
336
|
+
parts.push(node.value);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
if (defaultTreeAdapter.isCommentNode(node))
|
|
340
|
+
return;
|
|
341
|
+
if (defaultTreeAdapter.isElementNode(node)) {
|
|
342
|
+
const tag = node.tagName.toLowerCase();
|
|
343
|
+
if (SKIPPED_TEXT_ELEMENTS.has(tag))
|
|
344
|
+
return;
|
|
345
|
+
const block = BLOCK_ELEMENTS.has(tag);
|
|
346
|
+
if (block)
|
|
347
|
+
parts.push("\n\n");
|
|
348
|
+
for (const child of node.childNodes)
|
|
349
|
+
visit(child);
|
|
350
|
+
if (block)
|
|
351
|
+
parts.push("\n\n");
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
if ("childNodes" in node) {
|
|
355
|
+
for (const child of node.childNodes)
|
|
356
|
+
visit(child);
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
visit(document);
|
|
360
|
+
return parts
|
|
361
|
+
.join("")
|
|
362
|
+
.split(/\n\s*\n/)
|
|
363
|
+
.map((para) => para.replace(/\s+/g, " ").trim())
|
|
364
|
+
.filter((para) => para.length > 0)
|
|
365
|
+
.join("\n\n");
|
|
366
|
+
}
|
|
367
|
+
//# sourceMappingURL=widget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widget.js","sourceRoot":"","sources":["../../src/parser/widget.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"criticmarkup.js","sourceRoot":"","sources":["../../src/validator/criticmarkup.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,yEAAyE;AACzE,yEAAyE;AACzE,MAAM,aAAa,GAAG,mBAAmB,CAAC,MAAM,CAC9C,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,oBAAoB,CACpC,CAAC;AAEF,MAAM,YAAY,GAAG;IACnB,UAAU;IACV,UAAU;IACV,WAAW;IACX,SAAS;IACT,oBAAoB;IACpB,oBAAoB;
|
|
1
|
+
{"version":3,"file":"criticmarkup.js","sourceRoot":"","sources":["../../src/validator/criticmarkup.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,yEAAyE;AACzE,yEAAyE;AACzE,MAAM,aAAa,GAAG,mBAAmB,CAAC,MAAM,CAC9C,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,oBAAoB,CACpC,CAAC;AAEF,MAAM,YAAY,GAAG;IACnB,UAAU;IACV,UAAU;IACV,WAAW;IACX,SAAS;IACT,oBAAoB;IACpB,oBAAoB;IACpB,UAAU;CACX,CAAC;AAEF,2DAA2D;AAC3D,MAAM,UAAU,yBAAyB,CAAC,IAAY;IACpD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AAChF,CAAC;AAED,8DAA8D;AAC9D,SAAS,OAAO,CAAC,KAAa;IAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3C,OAAO,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC;AACtE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,OAAe,EACf,IAAY;IAEZ,MAAM,KAAK,GAAkD,EAAE,CAAC;IAEhE,KAAK,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,aAAa,EAAE,CAAC;QACzC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAM,CAAC;YAC3B,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;YACxD,KAAK,CAAC,IAAI,CAAC;gBACT,KAAK;gBACL,KAAK,EAAE;oBACL,IAAI;oBACJ,IAAI;oBACJ,OAAO,EAAE,wBAAwB,IAAI,gBAAgB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;oBACxE,UAAU,EACR,+DAA+D;wBAC/D,+DAA+D;oBACjE,QAAQ,EAAE,SAAS;iBACpB;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,gEAAgE;IAChE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lens-content-processor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.42.0",
|
|
4
4
|
"description": "Parser and validator for Lens educational content (Markdown modules, lenses, learning outcomes)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"katex": "^0.16.47",
|
|
45
45
|
"mdast-util-to-string": "^4.0.0",
|
|
46
|
+
"parse5": "^7.3.0",
|
|
46
47
|
"remark-directive": "^4.0.0",
|
|
47
48
|
"remark-gfm": "^4.0.1",
|
|
48
49
|
"remark-math": "^6.0.0",
|