lens-content-processor 0.49.0 → 0.51.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/bundler/article.d.ts +56 -45
- package/dist/bundler/article.js +129 -51
- package/dist/bundler/article.js.map +1 -1
- package/dist/cli.js +19 -0
- package/dist/cli.js.map +1 -1
- package/dist/content-schema.d.ts +14 -0
- package/dist/content-schema.js +33 -0
- package/dist/content-schema.js.map +1 -1
- package/dist/course-graph.d.ts +2 -0
- package/dist/course-graph.js +190 -0
- package/dist/course-graph.js.map +1 -0
- package/dist/flattener/index.js +64 -38
- package/dist/flattener/index.js.map +1 -1
- package/dist/index.d.ts +21 -2
- package/dist/index.js +27 -97
- package/dist/index.js.map +1 -1
- package/dist/markdown-parse.d.ts +5 -0
- package/dist/markdown-parse.js +33 -0
- package/dist/markdown-parse.js.map +1 -0
- package/dist/parser/article-elements.d.ts +139 -0
- package/dist/parser/article-elements.js +489 -0
- package/dist/parser/article-elements.js.map +1 -0
- package/dist/parser/article.d.ts +4 -0
- package/dist/parser/article.js +7 -4
- package/dist/parser/article.js.map +1 -1
- package/dist/parser/code-fence.d.ts +7 -0
- package/dist/parser/code-fence.js +34 -0
- package/dist/parser/code-fence.js.map +1 -0
- package/dist/parser/frames.d.ts +51 -0
- package/dist/parser/frames.js +116 -0
- package/dist/parser/frames.js.map +1 -0
- package/dist/parser/learning-outcome.js +4 -2
- package/dist/parser/learning-outcome.js.map +1 -1
- package/dist/parser/lens.d.ts +14 -1
- package/dist/parser/lens.js +28 -20
- package/dist/parser/lens.js.map +1 -1
- package/dist/parser/module.js +7 -27
- package/dist/parser/module.js.map +1 -1
- package/dist/parser/response-segments.d.ts +2 -0
- package/dist/parser/response-segments.js +2 -2
- package/dist/parser/response-segments.js.map +1 -1
- package/dist/parser/sections.d.ts +21 -1
- package/dist/parser/sections.js +94 -14
- package/dist/parser/sections.js.map +1 -1
- package/dist/parser/survey.js +9 -5
- package/dist/parser/survey.js.map +1 -1
- package/dist/reference-graph.d.ts +3 -0
- package/dist/reference-graph.js +11 -7
- package/dist/reference-graph.js.map +1 -1
- package/dist/same-page-links.js +3 -18
- package/dist/same-page-links.js.map +1 -1
- package/dist/source-location.js +6 -1
- package/dist/source-location.js.map +1 -1
- package/dist/validator/article-structure.js +25 -5
- package/dist/validator/article-structure.js.map +1 -1
- package/dist/validator/directives.js +61 -58
- package/dist/validator/directives.js.map +1 -1
- package/dist/validator/emphasis.js +1 -1
- package/dist/validator/emphasis.js.map +1 -1
- package/dist/validator/same-lens-links.js +3 -15
- package/dist/validator/same-lens-links.js.map +1 -1
- package/dist/validator/test-segments.js +1 -1
- package/dist/validator/tier.d.ts +2 -2
- package/dist/validator/tier.js +20 -18
- package/dist/validator/tier.js.map +1 -1
- package/package.json +1 -1
- package/dist/validator/article-imports.d.ts +0 -68
- package/dist/validator/article-imports.js +0 -265
- package/dist/validator/article-imports.js.map +0 -1
- package/dist/validator/markdown-parse.d.ts +0 -3
- package/dist/validator/markdown-parse.js +0 -22
- package/dist/validator/markdown-parse.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-schema.js","sourceRoot":"","sources":["../src/content-schema.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAsBlG,SAAS,aAAa,CACpB,QAAkB,EAClB,QAAkB;IAElB,OAAO;QACL,cAAc,EAAE,QAAQ;QACxB,cAAc,EAAE,QAAQ;QACxB,SAAS,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,QAAQ,CAAC;KACtC,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CACpB,QAAkB,EAClB,QAAkB,EAClB,aAAuB;IAEvB,OAAO;QACL,cAAc,EAAE,QAAQ;QACxB,cAAc,EAAE,QAAQ;QACxB,SAAS,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,QAAQ,CAAC;QACrC,aAAa;KACd,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAsC;IAChE,MAAM,EAAE,aAAa,CACnB,CAAC,MAAM,EAAE,OAAO,CAAC,EACjB,CAAC,WAAW,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,CAC1C;IACD,MAAM,EAAE,aAAa,CACnB,CAAC,MAAM,EAAE,OAAO,CAAC,EACjB;QACE,IAAI;QACJ,cAAc;QACd,MAAM;QACN,cAAc;QACd,cAAc;QACd,oBAAoB;QACpB,aAAa;QACb,2DAA2D;QAC3D,qEAAqE;QACrE,+DAA+D;QAC/D,aAAa;QACb,eAAe;QACf,UAAU;QACV,iBAAiB;QACjB,mBAAmB;KACpB,CACF;IACD,IAAI,EAAE,aAAa,CACjB,CAAC,IAAI,CAAC,EACN;QACE,OAAO;QACP,MAAM;QACN,mBAAmB;QACnB,MAAM;QACN,mBAAmB;QACnB,kBAAkB;QAClB,iBAAiB;QACjB,eAAe;KAChB,CACF;IACD,kBAAkB,EAAE,aAAa,CAC/B,CAAC,IAAI,CAAC,EACN,CAAC,YAAY,EAAE,kBAAkB,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,CAC1E;IACD,OAAO,EAAE,aAAa,CACpB,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,CAAC,EAC9C;QACE,SAAS;QACT,aAAa;QACb,MAAM;QACN,KAAK;QACL,oBAAoB;QACpB,qBAAqB;KACtB,CACF;IACD,kBAAkB,EAAE,aAAa,CAC/B,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC;IAC3B,sEAAsE;IACtE,oDAAoD;IACpD,CAAC,MAAM,EAAE,qBAAqB,EAAE,MAAM,EAAE,IAAI,CAAC,CAC9C;IACD,wEAAwE;IACxE,sEAAsE;IACtE,qDAAqD;IACrD,MAAM,EAAE,aAAa,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IAC1C,4EAA4E;IAC5E,2DAA2D;IAC3D,MAAM,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChD,yEAAyE;IACzE,sEAAsE;IACtE,MAAM,EAAE,aAAa,CACnB,CAAC,IAAI,CAAC,EACN,CAAC,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,CAAC,CACjD;CACF,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAsC;IACvE,IAAI,EAAE,aAAa,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC;IACxC,yEAAyE;IACzE,iBAAiB;IACjB,QAAQ,EAAE,aAAa,CACrB,CAAC,SAAS,EAAE,KAAK,CAAC,EAClB,CAAC,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,CAAC,EACjD,CAAC,UAAU,EAAE,OAAO,CAAC,CACtB;IACD,yEAAyE;IACzE,gDAAgD;IAChD,MAAM,EAAE,aAAa,CACnB,CAAC,SAAS,EAAE,KAAK,CAAC,EAClB,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,CAAC,EAC1D,CAAC,UAAU,CAAC,CACb;IACD,oEAAoE;IACpE,MAAM,EAAE,aAAa,CACnB,CAAC,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,EAC7B,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,CAAC,EACnC,CAAC,OAAO,EAAE,UAAU,CAAC,CACtB;IACD,wEAAwE;IACxE,qEAAqE;IACrE,WAAW;IACX,SAAS,EAAE,aAAa,CACtB,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,yBAAyB,CAAC,EACzD,CAAC,UAAU,CAAC,EACZ,CAAC,UAAU,CAAC,CACb;CACF,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AAC5C,0EAA0E;AAC1E,qEAAqE;AACrE,MAAM,iBAAiB,GAAG;IACxB,UAAU;IACV,uBAAuB;IACvB,gBAAgB;CACjB,CAAC;AACF,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;AACxD,MAAM,oBAAoB,GAAG,aAAa,CACxC,iBAAiB,EACjB;IACE,GAAG,iBAAiB;IACpB,yBAAyB;IACzB,WAAW;IACX,UAAU;IACV,aAAa;IACb,eAAe;CAChB,EACD,CAAC,GAAG,gBAAgB,EAAE,eAAe,CAAC,CACvC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAsC;IAChE,IAAI,EAAE,aAAa,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;IAC5D,yEAAyE;IACzE,wEAAwE;IACxE,oEAAoE;IACpE,IAAI,EAAE,aAAa,CACjB,CAAC,cAAc,CAAC,EAChB;QACE,mBAAmB;QACnB,6BAA6B;QAC7B,8BAA8B;KAC/B,EACD,CAAC,6BAA6B,EAAE,8BAA8B,CAAC,CAChE;IACD,6EAA6E;IAC7E,4EAA4E;IAC5E,yEAAyE;IACzE,uEAAuE;IACvE,kCAAkC;IAClC,OAAO,EAAE,aAAa,CACpB,EAAE,EACF,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,EACpC,CAAC,UAAU,CAAC,CACb;IACD,KAAK,EAAE,aAAa,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;IAC5E,wEAAwE;IACxE,0EAA0E;IAC1E,wEAAwE;IACxE,QAAQ,EAAE,aAAa,CACrB,oBAAoB,CAAC,cAAc,EACnC,CAAC,GAAG,oBAAoB,CAAC,cAAc,EAAE,UAAU,EAAE,mBAAmB,CAAC,EACzE,CAAC,GAAG,oBAAoB,CAAC,aAAa,EAAE,UAAU,CAAC,CACpD;IACD,QAAQ,EAAE,aAAa,CACrB,CAAC,IAAI,EAAE,SAAS,EAAE,iBAAiB,CAAC,EACpC;QACE,iBAAiB;QACjB,yBAAyB;QACzB,mBAAmB;QACnB,UAAU;QACV,UAAU;KACX,EACD,CAAC,mBAAmB,EAAE,UAAU,EAAE,UAAU,CAAC,CAC9C;IACD,2EAA2E;IAC3E,gFAAgF;IAChF,SAAS,EAAE,aAAa,CACtB,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,yBAAyB,CAAC,EACzD,CAAC,UAAU,CAAC,EACZ,CAAC,UAAU,CAAC,CACb;IACD,KAAK,EAAE,aAAa,CAClB,EAAE,EACF;QACE,QAAQ;QACR,MAAM;QACN,IAAI;QACJ,QAAQ;QACR,OAAO;QACP,cAAc;QACd,SAAS;QACT,UAAU;KACX,EACD,CAAC,UAAU,CAAC,CACb;IACD,qEAAqE;IACrE,6DAA6D;IAC7D,uEAAuE;IACvE,sEAAsE;IACtE,MAAM,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"content-schema.js","sourceRoot":"","sources":["../src/content-schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// src/course-graph.ts
|
|
2
|
+
//
|
|
3
|
+
// Ordered per-course checks that no single file can see. A course is a walk:
|
|
4
|
+
// course -> module -> learning outcome -> lens -> card, in document order.
|
|
5
|
+
//
|
|
6
|
+
// course-graph.names-unreached-lens text names another lens by its title, and
|
|
7
|
+
// the course never includes that lens, so a student cannot have read it.
|
|
8
|
+
// Found live 2026-09-24: AI Futures "What a Curve Licenses" told its grader
|
|
9
|
+
// the student had read "When Progress Jumps", which a rebuild had moved out
|
|
10
|
+
// of the course.
|
|
11
|
+
// course-graph.names-later-lens a tutor-facing field (grader or tutor
|
|
12
|
+
// instructions) names a lens the course includes only later, so it assumes
|
|
13
|
+
// a reading the student has not reached yet. Prose previews are not flagged.
|
|
14
|
+
//
|
|
15
|
+
// Warnings, not errors: matching titles in prose is a heuristic (titles under
|
|
16
|
+
// three words are skipped as too generic; a lens title inside an article title
|
|
17
|
+
// is taken to name the article). Runs in cli.ts, not processContent, because it
|
|
18
|
+
// needs every file at once (no per-file cache) and should fail softly.
|
|
19
|
+
// Link syntax and resolution are shared with reference-graph.ts.
|
|
20
|
+
import { WIKILINK_RE, resolveReference as resolve } from "./reference-graph.js";
|
|
21
|
+
import { parseFrontmatter } from "./parser/frontmatter.js";
|
|
22
|
+
import { stripAuthoringMarkup, stripAuthoringMarkupForValidation, } from "./authoring-markup.js";
|
|
23
|
+
import { buildTagMap, buildTierMap } from "./validator/tier.js";
|
|
24
|
+
const FRONTMATTER_RE = /^---\n[\s\S]*?\n---\n/;
|
|
25
|
+
function frontmatterTitle(path, content) {
|
|
26
|
+
const { frontmatter } = parseFrontmatter(stripAuthoringMarkup(content), path);
|
|
27
|
+
const t = frontmatter.title;
|
|
28
|
+
if (typeof t === "string" && t.trim())
|
|
29
|
+
return t.trim();
|
|
30
|
+
return path
|
|
31
|
+
.replace(/^.*\//, "")
|
|
32
|
+
.replace(/\.md$/, "")
|
|
33
|
+
.replace(/^[A-Z0-9]+ - /, "");
|
|
34
|
+
}
|
|
35
|
+
/** What a student-facing walk reads in a file: no frontmatter, comments, inline code,
|
|
36
|
+
* or Learning Outcome "Suggested Lenses" (not served; prod W1 API, 2026-09-24). */
|
|
37
|
+
function readable(path, content) {
|
|
38
|
+
// the Validation variant keeps every newline, so line numbers stay true
|
|
39
|
+
let t = stripAuthoringMarkupForValidation(content).replace(FRONTMATTER_RE, (m) => m.replace(/[^\n]/g, ""));
|
|
40
|
+
t = t.replace(/`[^`\n]*`/g, "");
|
|
41
|
+
if (path.startsWith("Learning Outcomes/"))
|
|
42
|
+
t = t.split(/^# Suggested Lenses/m)[0];
|
|
43
|
+
return t;
|
|
44
|
+
}
|
|
45
|
+
// Only these links put a file in front of the student. A wikilink inside
|
|
46
|
+
// grader text or prose does not, so it must not count as "reached".
|
|
47
|
+
const STRUCTURAL = /^(source::|#+ )|::card\[\[/;
|
|
48
|
+
/** Files a course reaches, in first-visit (preorder, document-order) sequence. */
|
|
49
|
+
function walk(course, files, text) {
|
|
50
|
+
const order = new Map();
|
|
51
|
+
const visit = (path) => {
|
|
52
|
+
order.set(path, order.size);
|
|
53
|
+
for (const line of text(path).split("\n")) {
|
|
54
|
+
if (!STRUCTURAL.test(line))
|
|
55
|
+
continue;
|
|
56
|
+
for (const m of line.matchAll(WIKILINK_RE)) {
|
|
57
|
+
const next = resolve(m[1], path, files);
|
|
58
|
+
if (next && !order.has(next))
|
|
59
|
+
visit(next);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
visit(course);
|
|
64
|
+
return order;
|
|
65
|
+
}
|
|
66
|
+
/** Lens title -> lens paths (titles repeat across course versions), for titles
|
|
67
|
+
* specific enough to match in prose. */
|
|
68
|
+
function lensTitles(files) {
|
|
69
|
+
const articles = [];
|
|
70
|
+
for (const [p, c] of files)
|
|
71
|
+
if (p.startsWith("articles/"))
|
|
72
|
+
articles.push(frontmatterTitle(p, c).toLowerCase());
|
|
73
|
+
const titles = new Map();
|
|
74
|
+
for (const [p, c] of files) {
|
|
75
|
+
if (!p.startsWith("Lenses/") || !p.endsWith(".md"))
|
|
76
|
+
continue;
|
|
77
|
+
const t = frontmatterTitle(p, c);
|
|
78
|
+
if (t.split(/\s+/).length < 3)
|
|
79
|
+
continue;
|
|
80
|
+
if (articles.some((a) => a.includes(t.toLowerCase())))
|
|
81
|
+
continue;
|
|
82
|
+
titles.set(t, [...(titles.get(t) ?? []), p]);
|
|
83
|
+
}
|
|
84
|
+
return titles;
|
|
85
|
+
}
|
|
86
|
+
function escape(s) {
|
|
87
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
88
|
+
}
|
|
89
|
+
// Fields whose text the tutor or grader reads as a statement of what the student has done.
|
|
90
|
+
const TUTOR_FIELD = /^(assessment-instructions|feedback-instructions|instructions|ai-instructions|summary_for_tutor)::/;
|
|
91
|
+
export function courseGraphIssues(files) {
|
|
92
|
+
const titles = lensTitles(files);
|
|
93
|
+
if (!titles.size)
|
|
94
|
+
return [];
|
|
95
|
+
const byTitle = [...titles.keys()]
|
|
96
|
+
.sort((a, b) => b.length - a.length)
|
|
97
|
+
.map(escape)
|
|
98
|
+
.join("|");
|
|
99
|
+
const pattern = new RegExp(`(?<![\\w])(?:${byTitle})(?![\\w])`, "g");
|
|
100
|
+
const tier = buildTierMap(buildTagMap(files));
|
|
101
|
+
const memo = new Map();
|
|
102
|
+
const text = (p) => {
|
|
103
|
+
if (!memo.has(p))
|
|
104
|
+
memo.set(p, readable(p, files.get(p) ?? ""));
|
|
105
|
+
return memo.get(p);
|
|
106
|
+
};
|
|
107
|
+
const mentionMemo = new Map();
|
|
108
|
+
const mentions = (file) => {
|
|
109
|
+
if (mentionMemo.has(file))
|
|
110
|
+
return mentionMemo.get(file);
|
|
111
|
+
const out = [];
|
|
112
|
+
let tutorFacing = false;
|
|
113
|
+
text(file)
|
|
114
|
+
.split("\n")
|
|
115
|
+
.forEach((line, i) => {
|
|
116
|
+
if (/^\s*#/.test(line)) {
|
|
117
|
+
tutorFacing = false;
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (/^[a-z_-]+::/.test(line))
|
|
121
|
+
tutorFacing = TUTOR_FIELD.test(line);
|
|
122
|
+
if (line.startsWith("source::"))
|
|
123
|
+
return;
|
|
124
|
+
for (const m of line.matchAll(pattern))
|
|
125
|
+
out.push({ line: i + 1, title: m[0], tutorFacing });
|
|
126
|
+
});
|
|
127
|
+
mentionMemo.set(file, out);
|
|
128
|
+
return out;
|
|
129
|
+
};
|
|
130
|
+
const found = new Map();
|
|
131
|
+
for (const [coursePath, content] of files) {
|
|
132
|
+
if (!coursePath.startsWith("courses/"))
|
|
133
|
+
continue;
|
|
134
|
+
const slug = parseFrontmatter(stripAuthoringMarkup(content), coursePath)
|
|
135
|
+
.frontmatter.slug;
|
|
136
|
+
if (typeof slug !== "string" || !slug.trim())
|
|
137
|
+
continue;
|
|
138
|
+
const order = walk(coursePath, files, text);
|
|
139
|
+
for (const [file, idx] of order) {
|
|
140
|
+
if (!file.endsWith(".md") || file.startsWith("articles/"))
|
|
141
|
+
continue;
|
|
142
|
+
for (const { line, title, tutorFacing } of mentions(file)) {
|
|
143
|
+
const copies = titles.get(title);
|
|
144
|
+
if (copies.includes(file))
|
|
145
|
+
continue;
|
|
146
|
+
const reached = copies
|
|
147
|
+
.map((c) => order.get(c))
|
|
148
|
+
.filter((x) => x !== undefined);
|
|
149
|
+
const at = reached.length ? Math.min(...reached) : undefined;
|
|
150
|
+
if (at !== undefined && (at < idx || !tutorFacing))
|
|
151
|
+
continue;
|
|
152
|
+
const kind = at === undefined ? "never" : "later";
|
|
153
|
+
const key = `${file}|${title}|${kind}`;
|
|
154
|
+
const rec = found.get(key) ?? {
|
|
155
|
+
kind,
|
|
156
|
+
line,
|
|
157
|
+
title,
|
|
158
|
+
file,
|
|
159
|
+
courses: new Set(),
|
|
160
|
+
};
|
|
161
|
+
rec.courses.add(slug.trim());
|
|
162
|
+
found.set(key, rec);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return [...found.values()]
|
|
167
|
+
.map((r) => {
|
|
168
|
+
const lens = titles.get(r.title).join(" or ");
|
|
169
|
+
const courses = `course${r.courses.size > 1 ? "s" : ""} ${[...r.courses].sort().join(", ")}`;
|
|
170
|
+
return {
|
|
171
|
+
file: r.file,
|
|
172
|
+
line: r.line,
|
|
173
|
+
severity: "warning",
|
|
174
|
+
category: tier.get(r.file) === "wip" ? "wip" : "production",
|
|
175
|
+
...(r.kind === "never"
|
|
176
|
+
? {
|
|
177
|
+
code: "course-graph.names-unreached-lens",
|
|
178
|
+
message: `Mentions "${r.title}" (${lens}), a lens that ${courses} never include, so a student may not have read it`,
|
|
179
|
+
suggestion: "Add that lens to the course, or rewrite this text so it does not assume the student read it",
|
|
180
|
+
}
|
|
181
|
+
: {
|
|
182
|
+
code: "course-graph.names-later-lens",
|
|
183
|
+
message: `Tutor-facing text mentions "${r.title}" (${lens}), which ${courses} only include later, so the student has not read it yet at this point`,
|
|
184
|
+
suggestion: "Rewrite so the tutor does not assume that reading, or move the lens earlier",
|
|
185
|
+
}),
|
|
186
|
+
};
|
|
187
|
+
})
|
|
188
|
+
.sort((a, b) => (a.file + a.line).localeCompare(b.file + b.line));
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=course-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"course-graph.js","sourceRoot":"","sources":["../src/course-graph.ts"],"names":[],"mappings":"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"}
|
package/dist/flattener/index.js
CHANGED
|
@@ -2,10 +2,12 @@ import { resolveTextLinks, enrichCardLinks } from "./resolve-text-links.js";
|
|
|
2
2
|
import { checkTierViolation } from "../validator/tier.js";
|
|
3
3
|
import { parseModule } from "../parser/module.js";
|
|
4
4
|
import { parseLearningOutcome, } from "../parser/learning-outcome.js";
|
|
5
|
-
import { parseLens, } from "../parser/lens.js";
|
|
5
|
+
import { parseLens, convertSegment as parseRawSegment, } from "../parser/lens.js";
|
|
6
6
|
import { parseWikilink, resolveWikilinkPath, findFileWithExtension, findSimilarFiles, formatSuggestion, isSoleWikilink, findWikilinks, findBrokenPromptImports, } from "../parser/wikilink.js";
|
|
7
7
|
import { parsePrompt, isPromptPath } from "../parser/prompt.js";
|
|
8
8
|
import { parseWidget, resolveWidgetPath } from "../parser/widget.js";
|
|
9
|
+
import { prependFrames } from "../parser/frames.js";
|
|
10
|
+
import { ARTICLE_ELEMENT_KINDS, } from "../parser/article-elements.js";
|
|
9
11
|
import { toFlattenedResponseSegment } from "../parser/response-segments.js";
|
|
10
12
|
import { parseFrontmatter } from "../parser/frontmatter.js";
|
|
11
13
|
import { fileNameToSlug } from "../utils/slug.js";
|
|
@@ -301,13 +303,15 @@ function flattenSingleLens(lens, lensPath, files, visitedPaths, tierMap) {
|
|
|
301
303
|
const planned = articlePlan.get(i);
|
|
302
304
|
if (planned) {
|
|
303
305
|
errors.push(...planned.errors);
|
|
304
|
-
|
|
306
|
+
for (const segment of planned.segments) {
|
|
307
|
+
segments.push(prependFrames(segment, parsedSegment.frames));
|
|
308
|
+
}
|
|
305
309
|
continue;
|
|
306
310
|
}
|
|
307
311
|
const segmentResult = convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap, blockTargets);
|
|
308
312
|
errors.push(...segmentResult.errors);
|
|
309
313
|
if (segmentResult.segment) {
|
|
310
|
-
segments.push(segmentResult.segment);
|
|
314
|
+
segments.push(prependFrames(segmentResult.segment, parsedSegment.frames));
|
|
311
315
|
}
|
|
312
316
|
}
|
|
313
317
|
return { segments, errors };
|
|
@@ -493,7 +497,10 @@ export function flattenModule(modulePath, files, visitedPaths = new Set(), tierM
|
|
|
493
497
|
// groups[i] is the i-th `# Submodule:` (the whole module when flat), the
|
|
494
498
|
// same order recordOutcome counted in.
|
|
495
499
|
groups.forEach((group, i) => {
|
|
496
|
-
const outcomes = [
|
|
500
|
+
const outcomes = [
|
|
501
|
+
...moduleLevelOutcomes,
|
|
502
|
+
...(outcomesByGroup.get(i) ?? []),
|
|
503
|
+
];
|
|
497
504
|
for (const section of group.sections)
|
|
498
505
|
tagLensOutcomes(section, outcomes);
|
|
499
506
|
});
|
|
@@ -588,13 +595,15 @@ function buildTestSection(testRef, outcome, loPath, files, visitedPaths, tierMap
|
|
|
588
595
|
const planned = articlePlan.get(i);
|
|
589
596
|
if (planned) {
|
|
590
597
|
errors.push(...planned.errors);
|
|
591
|
-
|
|
598
|
+
for (const segment of planned.segments) {
|
|
599
|
+
testSegments.push(prependFrames(segment, parsedSegment.frames));
|
|
600
|
+
}
|
|
592
601
|
continue;
|
|
593
602
|
}
|
|
594
603
|
const segmentResult = convertSegment(parsedSegment, loPath, files, new Set(visitedPaths), tierMap, blockTargets);
|
|
595
604
|
errors.push(...segmentResult.errors);
|
|
596
605
|
if (segmentResult.segment) {
|
|
597
|
-
testSegments.push(segmentResult.segment);
|
|
606
|
+
testSegments.push(prependFrames(segmentResult.segment, parsedSegment.frames));
|
|
598
607
|
}
|
|
599
608
|
}
|
|
600
609
|
if (testSegments.length === 0)
|
|
@@ -1180,6 +1189,13 @@ function planLensArticles(parsedSegments, lensPath, files, visitedPaths, tierMap
|
|
|
1180
1189
|
});
|
|
1181
1190
|
continue;
|
|
1182
1191
|
}
|
|
1192
|
+
if (excerpt.warning) {
|
|
1193
|
+
entry.errors.push({
|
|
1194
|
+
...excerpt.warning,
|
|
1195
|
+
file: lensPath,
|
|
1196
|
+
line: getSourceLine(parsedSegment),
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1183
1199
|
const makeArticleSegment = (content) => {
|
|
1184
1200
|
const segment = {
|
|
1185
1201
|
type: "article",
|
|
@@ -1223,9 +1239,10 @@ function planLensArticles(parsedSegments, lensPath, files, visitedPaths, tierMap
|
|
|
1223
1239
|
entry.segments.push(segment);
|
|
1224
1240
|
continue;
|
|
1225
1241
|
}
|
|
1226
|
-
// The excerpt contains
|
|
1242
|
+
// The excerpt contains markers: emit prose/element parts, each framed
|
|
1243
|
+
// by the lifted callouts it sits in.
|
|
1227
1244
|
const partSegments = [];
|
|
1228
|
-
let
|
|
1245
|
+
let elementFailed = false;
|
|
1229
1246
|
for (const part of excerpt.parts) {
|
|
1230
1247
|
if (part.kind === "prose") {
|
|
1231
1248
|
const segment = makeArticleSegment(part.content);
|
|
@@ -1233,39 +1250,37 @@ function planLensArticles(parsedSegments, lensPath, files, visitedPaths, tierMap
|
|
|
1233
1250
|
segment.skipStartMarker = true;
|
|
1234
1251
|
if (part.contiguousWithNext)
|
|
1235
1252
|
segment.skipEndMarker = true;
|
|
1236
|
-
partSegments.push(segment);
|
|
1253
|
+
partSegments.push(prependFrames(segment, part.frames));
|
|
1237
1254
|
continue;
|
|
1238
1255
|
}
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
tierMap,
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
? resolveVideoSegment(`[[${part.target}]]`, part.from, part.to, {
|
|
1248
|
-
...importCtx,
|
|
1249
|
-
notFoundCode: "article.video-import-not-found",
|
|
1250
|
-
visitedPaths,
|
|
1251
|
-
})
|
|
1252
|
-
: resolveWidgetSegment(`[[${part.target}]]`, { height: part.height }, {
|
|
1253
|
-
...importCtx,
|
|
1254
|
-
notFoundCode: "article.widget-embed-not-found",
|
|
1256
|
+
// The element is the RawSegment its `####` twin would be: the same
|
|
1257
|
+
// parser and flattener conversions apply, resolved from the article.
|
|
1258
|
+
// Its field errors were reported in the article's own parse pass.
|
|
1259
|
+
const parsed = parseRawSegment(part.raw, "lens", articlePath).segment;
|
|
1260
|
+
const converted = parsed &&
|
|
1261
|
+
convertSegment(parsed, articlePath, files, visitedPaths, tierMap, new Map(), {
|
|
1262
|
+
errorLine: findImportLine(articleContent, part.rawLine),
|
|
1263
|
+
notFoundCode: `article.${ARTICLE_ELEMENT_KINDS[part.raw.type].code}-not-found`,
|
|
1255
1264
|
});
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1265
|
+
if (converted)
|
|
1266
|
+
entry.errors.push(...converted.errors);
|
|
1267
|
+
if (!converted?.segment) {
|
|
1268
|
+
elementFailed = true;
|
|
1259
1269
|
continue;
|
|
1260
1270
|
}
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1271
|
+
const segment = converted.segment;
|
|
1272
|
+
if (segment.type === "video" ||
|
|
1273
|
+
segment.type === "widget" ||
|
|
1274
|
+
segment.type === "question") {
|
|
1275
|
+
segment.partOfArticle = true;
|
|
1276
|
+
// Widgets carry no optional flag (they gate nothing unless required).
|
|
1277
|
+
if (parsedSegment.optional && segment.type !== "widget")
|
|
1278
|
+
segment.optional = true;
|
|
1279
|
+
}
|
|
1280
|
+
partSegments.push(prependFrames(attachSourceLine(segment, getSourceLine(parsedSegment)), part.frames));
|
|
1266
1281
|
}
|
|
1267
|
-
if (
|
|
1268
|
-
// A broken
|
|
1282
|
+
if (elementFailed) {
|
|
1283
|
+
// A broken element must not leave a half-split article with dangling
|
|
1269
1284
|
// seam flags: fall back to the un-split excerpt (error already
|
|
1270
1285
|
// recorded above).
|
|
1271
1286
|
const segment = makeArticleSegment(excerpt.content);
|
|
@@ -1425,7 +1440,10 @@ export function expandPromptImports(value, fieldName, lensPath, files, tierMap)
|
|
|
1425
1440
|
* For article and video, this involves extracting content from source files.
|
|
1426
1441
|
* Source comes from the parsed segment itself (set via inheritance in parseLens).
|
|
1427
1442
|
*/
|
|
1428
|
-
function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap, blockTargets = new Map()
|
|
1443
|
+
function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap, blockTargets = new Map(),
|
|
1444
|
+
// Set for elements declared inside an article body: the line the element
|
|
1445
|
+
// sits on there, and the error code a missing source file gets.
|
|
1446
|
+
origin) {
|
|
1429
1447
|
const errors = [];
|
|
1430
1448
|
switch (parsedSegment.type) {
|
|
1431
1449
|
case "text": {
|
|
@@ -1488,7 +1506,9 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap, b
|
|
|
1488
1506
|
const result = resolveVideoSegment(parsedSegment.source, parsedSegment.fromTimeStr, parsedSegment.toTimeStr, {
|
|
1489
1507
|
resolveFrom: lensPath,
|
|
1490
1508
|
errorFile: lensPath,
|
|
1491
|
-
|
|
1509
|
+
...(origin
|
|
1510
|
+
? { errorLine: origin.errorLine, notFoundCode: origin.notFoundCode }
|
|
1511
|
+
: { excerptErrorLine: getSourceLine(parsedSegment) }),
|
|
1492
1512
|
files,
|
|
1493
1513
|
visitedPaths,
|
|
1494
1514
|
tierMap,
|
|
@@ -1701,7 +1721,13 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap, b
|
|
|
1701
1721
|
};
|
|
1702
1722
|
}
|
|
1703
1723
|
case "widget": {
|
|
1704
|
-
const result = resolveWidgetSegment(parsedSegment.source, { height: parsedSegment.height, required: parsedSegment.required }, {
|
|
1724
|
+
const result = resolveWidgetSegment(parsedSegment.source, { height: parsedSegment.height, required: parsedSegment.required }, {
|
|
1725
|
+
resolveFrom: lensPath,
|
|
1726
|
+
errorFile: lensPath,
|
|
1727
|
+
...origin,
|
|
1728
|
+
files,
|
|
1729
|
+
tierMap,
|
|
1730
|
+
});
|
|
1705
1731
|
errors.push(...result.errors);
|
|
1706
1732
|
return {
|
|
1707
1733
|
segment: result.segment &&
|