lens-content-processor 0.27.0 → 0.33.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/authoring-markup.d.ts +11 -0
- package/dist/authoring-markup.js +52 -0
- package/dist/authoring-markup.js.map +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +6 -2
- package/dist/cli.js.map +1 -1
- package/dist/content-schema.js +17 -1
- package/dist/content-schema.js.map +1 -1
- package/dist/dedupe-errors.js +7 -1
- package/dist/dedupe-errors.js.map +1 -1
- package/dist/flattener/index.js +90 -46
- package/dist/flattener/index.js.map +1 -1
- package/dist/flattener/resolve-text-links.js +6 -2
- package/dist/flattener/resolve-text-links.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +20 -1
- package/dist/index.js.map +1 -1
- package/dist/parser/article.js +34 -32
- package/dist/parser/article.js.map +1 -1
- package/dist/parser/course.d.ts +0 -10
- package/dist/parser/course.js +16 -14
- package/dist/parser/course.js.map +1 -1
- package/dist/parser/learning-outcome.d.ts +1 -0
- package/dist/parser/learning-outcome.js +28 -38
- package/dist/parser/learning-outcome.js.map +1 -1
- package/dist/parser/lens.d.ts +27 -10
- package/dist/parser/lens.js +160 -32
- package/dist/parser/lens.js.map +1 -1
- package/dist/parser/module.js +37 -18
- package/dist/parser/module.js.map +1 -1
- package/dist/parser/sections.d.ts +2 -1
- package/dist/parser/sections.js +5 -3
- package/dist/parser/sections.js.map +1 -1
- package/dist/parser/survey.js +16 -10
- package/dist/parser/survey.js.map +1 -1
- package/dist/source-location.d.ts +2 -0
- package/dist/source-location.js +12 -0
- package/dist/source-location.js.map +1 -0
- package/dist/validator/article-review-provenance.d.ts +5 -0
- package/dist/validator/article-review-provenance.js +57 -0
- package/dist/validator/article-review-provenance.js.map +1 -0
- package/dist/validator/article-structure.d.ts +8 -0
- package/dist/validator/article-structure.js +674 -0
- package/dist/validator/article-structure.js.map +1 -0
- package/dist/validator/directives.js +42 -0
- package/dist/validator/directives.js.map +1 -1
- package/dist/validator/emphasis.js +126 -2
- package/dist/validator/emphasis.js.map +1 -1
- package/dist/validator/html-tags.js +87 -2
- package/dist/validator/html-tags.js.map +1 -1
- package/dist/validator/math.js +66 -9
- package/dist/validator/math.js.map +1 -1
- package/dist/validator/output-integrity.js +7 -1
- package/dist/validator/output-integrity.js.map +1 -1
- package/dist/validator/same-lens-links.d.ts +4 -0
- package/dist/validator/same-lens-links.js +297 -0
- package/dist/validator/same-lens-links.js.map +1 -0
- package/dist/validator/suppressions.d.ts +42 -0
- package/dist/validator/suppressions.js +97 -0
- package/dist/validator/suppressions.js.map +1 -0
- package/dist/validator/uuid.d.ts +1 -0
- package/dist/validator/uuid.js +2 -0
- package/dist/validator/uuid.js.map +1 -1
- package/package.json +9 -1
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
* Handles both inline (%% ... %% on same line) and block (multiline) comments.
|
|
4
4
|
*/
|
|
5
5
|
export declare function stripObsidianComments(content: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* Reject authoring markup while preserving source line numbers for validators.
|
|
8
|
+
* Publishing deliberately uses stripAuthoringMarkup() instead.
|
|
9
|
+
*/
|
|
10
|
+
export declare function stripAuthoringMarkupForValidation(content: string): string;
|
|
6
11
|
/**
|
|
7
12
|
* Strip CriticMarkup from content using reject-all-changes behavior. Each
|
|
8
13
|
* form's regex and publish replacement are defined once in CRITIC_MARKUP_FORMS
|
|
@@ -14,3 +19,9 @@ export declare function stripCriticMarkup(content: string): string;
|
|
|
14
19
|
* Call before parsing or publishing learner-facing content.
|
|
15
20
|
*/
|
|
16
21
|
export declare function stripAuthoringMarkup(content: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Copy learner-facing strings from a publishing parse onto the equivalent
|
|
24
|
+
* validation parse. Objects (and their non-enumerable source provenance) stay
|
|
25
|
+
* intact, as do validation-derived line numbers and other scalar metadata.
|
|
26
|
+
*/
|
|
27
|
+
export declare function usePublishedStrings<T>(validationValue: T, publishedValue: T): T;
|
package/dist/authoring-markup.js
CHANGED
|
@@ -6,6 +6,28 @@ import { CRITIC_MARKUP_FORMS } from "./criticmarkup-forms.js";
|
|
|
6
6
|
export function stripObsidianComments(content) {
|
|
7
7
|
return content.replace(/%%.*?%%/gs, "");
|
|
8
8
|
}
|
|
9
|
+
function preserveNewlines(match, replacement) {
|
|
10
|
+
const missing = (match.match(/\n/g)?.length ?? 0) - (replacement.match(/\n/g)?.length ?? 0);
|
|
11
|
+
return replacement + "\n".repeat(Math.max(0, missing));
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Reject authoring markup while preserving source line numbers for validators.
|
|
15
|
+
* Publishing deliberately uses stripAuthoringMarkup() instead.
|
|
16
|
+
*/
|
|
17
|
+
export function stripAuthoringMarkupForValidation(content) {
|
|
18
|
+
let result = content.replace(/%%.*?%%/gs, (match) => match.replace(/[^\n]/g, " "));
|
|
19
|
+
for (const form of CRITIC_MARKUP_FORMS) {
|
|
20
|
+
result = result.replace(form.re, (...args) => {
|
|
21
|
+
const match = String(args[0]);
|
|
22
|
+
const kept = form.rejected === "$1" ? String(args[1] ?? "") : "";
|
|
23
|
+
return preserveNewlines(match, kept);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
return result
|
|
27
|
+
.split("\n")
|
|
28
|
+
.map((line) => line.trimEnd())
|
|
29
|
+
.join("\n");
|
|
30
|
+
}
|
|
9
31
|
/**
|
|
10
32
|
* Strip CriticMarkup from content using reject-all-changes behavior. Each
|
|
11
33
|
* form's regex and publish replacement are defined once in CRITIC_MARKUP_FORMS
|
|
@@ -26,4 +48,34 @@ export function stripAuthoringMarkup(content) {
|
|
|
26
48
|
.map((line) => line.trimEnd())
|
|
27
49
|
.join("\n");
|
|
28
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Copy learner-facing strings from a publishing parse onto the equivalent
|
|
53
|
+
* validation parse. Objects (and their non-enumerable source provenance) stay
|
|
54
|
+
* intact, as do validation-derived line numbers and other scalar metadata.
|
|
55
|
+
*/
|
|
56
|
+
export function usePublishedStrings(validationValue, publishedValue) {
|
|
57
|
+
if (typeof validationValue === "string")
|
|
58
|
+
return publishedValue;
|
|
59
|
+
if (validationValue === null ||
|
|
60
|
+
publishedValue === null ||
|
|
61
|
+
typeof validationValue !== "object" ||
|
|
62
|
+
typeof publishedValue !== "object") {
|
|
63
|
+
return validationValue;
|
|
64
|
+
}
|
|
65
|
+
if (Array.isArray(validationValue) && Array.isArray(publishedValue)) {
|
|
66
|
+
const count = Math.min(validationValue.length, publishedValue.length);
|
|
67
|
+
for (let index = 0; index < count; index += 1) {
|
|
68
|
+
validationValue[index] = usePublishedStrings(validationValue[index], publishedValue[index]);
|
|
69
|
+
}
|
|
70
|
+
return validationValue;
|
|
71
|
+
}
|
|
72
|
+
const validationRecord = validationValue;
|
|
73
|
+
const publishedRecord = publishedValue;
|
|
74
|
+
for (const key of Object.keys(validationRecord)) {
|
|
75
|
+
if (key in publishedRecord) {
|
|
76
|
+
validationRecord[key] = usePublishedStrings(validationRecord[key], publishedRecord[key]);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return validationValue;
|
|
80
|
+
}
|
|
29
81
|
//# sourceMappingURL=authoring-markup.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authoring-markup.js","sourceRoot":"","sources":["../src/authoring-markup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACnD,OAAO,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,OAAO,mBAAmB,CAAC,MAAM,CAC/B,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,EACpD,OAAO,CACR,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,MAAM,QAAQ,GAAG,qBAAqB,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC;IACnE,0DAA0D;IAC1D,OAAO,QAAQ;SACZ,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;SAC7B,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
|
1
|
+
{"version":3,"file":"authoring-markup.js","sourceRoot":"","sources":["../src/authoring-markup.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
CHANGED
package/dist/cli.js
CHANGED
|
@@ -14,6 +14,7 @@ export function parseArgs(argv) {
|
|
|
14
14
|
let stdin = false;
|
|
15
15
|
let deferUrls = false;
|
|
16
16
|
let checkUrlsOnly = false;
|
|
17
|
+
let skipUrls = false;
|
|
17
18
|
for (let i = 0; i < args.length; i++) {
|
|
18
19
|
if (args[i] === "--output" || args[i] === "-o") {
|
|
19
20
|
outputPath = args[i + 1] || null;
|
|
@@ -28,11 +29,14 @@ export function parseArgs(argv) {
|
|
|
28
29
|
else if (args[i] === "--check-urls-only") {
|
|
29
30
|
checkUrlsOnly = true;
|
|
30
31
|
}
|
|
32
|
+
else if (args[i] === "--skip-urls") {
|
|
33
|
+
skipUrls = true;
|
|
34
|
+
}
|
|
31
35
|
else if (!args[i].startsWith("-")) {
|
|
32
36
|
vaultPath = args[i];
|
|
33
37
|
}
|
|
34
38
|
}
|
|
35
|
-
return { vaultPath, outputPath, stdin, deferUrls, checkUrlsOnly };
|
|
39
|
+
return { vaultPath, outputPath, stdin, deferUrls, checkUrlsOnly, skipUrls };
|
|
36
40
|
}
|
|
37
41
|
async function readStdin() {
|
|
38
42
|
const chunks = [];
|
|
@@ -121,7 +125,7 @@ async function main() {
|
|
|
121
125
|
staleUrlCount: cache.staleCount(result.urlsToValidate),
|
|
122
126
|
};
|
|
123
127
|
}
|
|
124
|
-
else if (result.urlsToValidate.length > 0) {
|
|
128
|
+
else if (!options.skipUrls && result.urlsToValidate.length > 0) {
|
|
125
129
|
const urlWarnings = await validateUrls(result.urlsToValidate, UrlCache.load());
|
|
126
130
|
// Re-dedupe: urlWarnings are appended after processContent already
|
|
127
131
|
// deduped, and can themselves repeat (same unreachable URL twice).
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,aAAa;AACb,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EACL,cAAc,GAIf,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,YAAY,EACZ,mBAAmB,GACpB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/content-schema.js
CHANGED
|
@@ -25,7 +25,16 @@ export const CONTENT_SCHEMAS = {
|
|
|
25
25
|
"partner-logo-small",
|
|
26
26
|
"partner-url",
|
|
27
27
|
]),
|
|
28
|
-
lens: contentSchema(["id"], [
|
|
28
|
+
lens: contentSchema(["id"], [
|
|
29
|
+
"title",
|
|
30
|
+
"tldr",
|
|
31
|
+
"summary_for_tutor",
|
|
32
|
+
"tags",
|
|
33
|
+
"min_chat_messages",
|
|
34
|
+
"duration_minutes",
|
|
35
|
+
"reading_minutes",
|
|
36
|
+
"tutor_minutes",
|
|
37
|
+
]),
|
|
29
38
|
"learning-outcome": contentSchema(["id"], ["discussion", "learning-outcome", "tags", "domain", "stage", "requires"]),
|
|
30
39
|
article: contentSchema(["title", "author", "source_url", "published"], [
|
|
31
40
|
"created",
|
|
@@ -34,6 +43,13 @@ export const CONTENT_SCHEMAS = {
|
|
|
34
43
|
"url",
|
|
35
44
|
"allowAuthorInTitle",
|
|
36
45
|
"allowUnreachableUrl",
|
|
46
|
+
"llm_reviewed",
|
|
47
|
+
"llm_review_version",
|
|
48
|
+
"llm_review_model",
|
|
49
|
+
"llm_review_digest",
|
|
50
|
+
"llm_review_source_digest",
|
|
51
|
+
"llm_review_source_fetched",
|
|
52
|
+
"llm_review_source_kind",
|
|
37
53
|
]),
|
|
38
54
|
"video-transcript": contentSchema(["title", "channel", "url"],
|
|
39
55
|
// from/to: default excerpt range applied when an embedding lens omits
|
|
@@ -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;KACd,CACF;IACD,IAAI,EAAE,aAAa,CACjB,CAAC,IAAI,CAAC,EACN,
|
|
1
|
+
{"version":3,"file":"content-schema.js","sourceRoot":"","sources":["../src/content-schema.ts"],"names":[],"mappings":"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"}
|
package/dist/dedupe-errors.js
CHANGED
|
@@ -14,6 +14,12 @@ export function dedupeErrors(errors) {
|
|
|
14
14
|
const seen = new Set();
|
|
15
15
|
const deduped = [];
|
|
16
16
|
for (const error of errors) {
|
|
17
|
+
// Output-integrity validation can see the same flattened segment with a
|
|
18
|
+
// resolved section title in the standalone pass and an empty title in an
|
|
19
|
+
// embedding module pass. The title is presentation context, not problem
|
|
20
|
+
// identity; retain the segment kind and ordinal so distinct segments are
|
|
21
|
+
// still reported independently.
|
|
22
|
+
const messageKey = error.message.replace(/^(Empty (?:text|article) segment|Empty video transcript) in ".*" (\(segment \d+\))$/, "$1 $2");
|
|
17
23
|
// \x1f (unit separator) joins the fields: file paths and messages can
|
|
18
24
|
// themselves contain spaces, so a printable separator could let two
|
|
19
25
|
// distinct errors collapse to the same key.
|
|
@@ -21,7 +27,7 @@ export function dedupeErrors(errors) {
|
|
|
21
27
|
error.file,
|
|
22
28
|
error.line ?? "",
|
|
23
29
|
error.severity,
|
|
24
|
-
|
|
30
|
+
messageKey,
|
|
25
31
|
].join("\x1f");
|
|
26
32
|
if (seen.has(key))
|
|
27
33
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dedupe-errors.js","sourceRoot":"","sources":["../src/dedupe-errors.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAAC,MAAsB;IACjD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,OAAO,GAAmB,EAAE,CAAC;IAEnC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,sEAAsE;QACtE,oEAAoE;QACpE,4CAA4C;QAC5C,MAAM,GAAG,GAAG;YACV,KAAK,CAAC,IAAI;YACV,KAAK,CAAC,IAAI,IAAI,EAAE;YAChB,KAAK,CAAC,QAAQ;YACd,
|
|
1
|
+
{"version":3,"file":"dedupe-errors.js","sourceRoot":"","sources":["../src/dedupe-errors.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAAC,MAAsB;IACjD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,OAAO,GAAmB,EAAE,CAAC;IAEnC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,wEAAwE;QACxE,yEAAyE;QACzE,wEAAwE;QACxE,yEAAyE;QACzE,gCAAgC;QAChC,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CACtC,qFAAqF,EACrF,OAAO,CACR,CAAC;QACF,sEAAsE;QACtE,oEAAoE;QACpE,4CAA4C;QAC5C,MAAM,GAAG,GAAG;YACV,KAAK,CAAC,IAAI;YACV,KAAK,CAAC,IAAI,IAAI,EAAE;YAChB,KAAK,CAAC,QAAQ;YACd,UAAU;SACX,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACf,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/flattener/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { parseFrontmatter } from "../parser/frontmatter.js";
|
|
|
9
9
|
import { fileNameToSlug } from "../utils/slug.js";
|
|
10
10
|
import { extractArticleExcerpt, bundleArticleWithCollapsed, } from "../bundler/article.js";
|
|
11
11
|
import { extractVideoExcerpt, resolveVideoRange, } from "../bundler/video.js";
|
|
12
|
+
import { attachSourceLine, getSourceLine } from "../source-location.js";
|
|
12
13
|
function countWords(text) {
|
|
13
14
|
return text.trim().split(/\s+/).filter(Boolean).length;
|
|
14
15
|
}
|
|
@@ -56,6 +57,43 @@ function videoSegmentSeconds(seg) {
|
|
|
56
57
|
return lastTimestamp - seg.from;
|
|
57
58
|
return Math.round((transcriptWords / SPOKEN_WORDS_PER_MINUTE) * 60);
|
|
58
59
|
}
|
|
60
|
+
/** The Section fields every lens read path copies verbatim from the parsed
|
|
61
|
+
* lens: identity, authored metadata, and segment-derived stats. Keeping them
|
|
62
|
+
* in one place means a new lens-level field is carried on all three paths
|
|
63
|
+
* (inline lens, module-referenced lens, standalone lens) by one change. */
|
|
64
|
+
function lensSectionFields(lens, segments, file, line, errors) {
|
|
65
|
+
const stats = computeSectionStats(segments);
|
|
66
|
+
// reading_minutes covers ALL content time including watching; a value
|
|
67
|
+
// below the lens's own video length is almost certainly "reading on top
|
|
68
|
+
// of the video" and would silently shrink the badge below the watch time
|
|
69
|
+
const videoMin = Math.ceil((stats.videoDurationSeconds ?? 0) / 60);
|
|
70
|
+
if (lens.readingMinutes !== undefined &&
|
|
71
|
+
videoMin > 0 &&
|
|
72
|
+
lens.readingMinutes < videoMin) {
|
|
73
|
+
errors.push({
|
|
74
|
+
file,
|
|
75
|
+
line,
|
|
76
|
+
message: `Field 'reading_minutes' is ${lens.readingMinutes}, less than the lens's ${videoMin} min of video (reading_minutes covers watch time too)`,
|
|
77
|
+
suggestion: "Set reading_minutes to the full content time including the video, or remove it to keep the computed estimate",
|
|
78
|
+
severity: "warning",
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
segments,
|
|
83
|
+
learningOutcomeId: null,
|
|
84
|
+
learningOutcomeName: null,
|
|
85
|
+
contentId: lens.id ?? null,
|
|
86
|
+
tldr: lens.tldr,
|
|
87
|
+
summaryForTutor: lens.summaryForTutor,
|
|
88
|
+
minChatMessages: lens.minChatMessages,
|
|
89
|
+
durationMinutes: lens.durationMinutes,
|
|
90
|
+
readingMinutes: lens.readingMinutes,
|
|
91
|
+
tutorMinutes: lens.tutorMinutes,
|
|
92
|
+
addToAiContext: lens.addToAiContext,
|
|
93
|
+
...stats,
|
|
94
|
+
displayType: computeDisplayType(segments),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
59
97
|
/** Compute word count and video duration from a section's segments. */
|
|
60
98
|
function computeSectionStats(segments) {
|
|
61
99
|
let words = 0;
|
|
@@ -646,23 +684,14 @@ function flattenLensSection(section, modulePath, files, visitedPaths, tierMap, i
|
|
|
646
684
|
const hideConflict = checkHideOptionalConflict(effectiveOptional, effectiveHide, modulePath, section.line);
|
|
647
685
|
if (hideConflict)
|
|
648
686
|
errors.push(hideConflict);
|
|
649
|
-
const resultSection = {
|
|
687
|
+
const resultSection = attachSourceLine({
|
|
650
688
|
type: "lens",
|
|
651
689
|
meta: { title: inlineLens.title || section.title },
|
|
652
|
-
segments,
|
|
653
690
|
sourcePath: modulePath,
|
|
654
691
|
optional: effectiveOptional,
|
|
655
692
|
...(effectiveHide && { hide: true }),
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
contentId: inlineLens.id ?? null,
|
|
659
|
-
tldr: inlineLens.tldr,
|
|
660
|
-
summaryForTutor: inlineLens.summaryForTutor,
|
|
661
|
-
minChatMessages: inlineLens.minChatMessages,
|
|
662
|
-
addToAiContext: inlineLens.addToAiContext,
|
|
663
|
-
...computeSectionStats(segments),
|
|
664
|
-
displayType: computeDisplayType(segments),
|
|
665
|
-
};
|
|
693
|
+
...lensSectionFields(inlineLens, segments, modulePath, section.line, errors),
|
|
694
|
+
}, section.line);
|
|
666
695
|
sections.push(resultSection);
|
|
667
696
|
return { sections, errors };
|
|
668
697
|
}
|
|
@@ -746,23 +775,14 @@ function flattenLensSection(section, modulePath, files, visitedPaths, tierMap, i
|
|
|
746
775
|
const hideConflict = checkHideOptionalConflict(effectiveOptional, effectiveHide, modulePath, section.line);
|
|
747
776
|
if (hideConflict)
|
|
748
777
|
errors.push(hideConflict);
|
|
749
|
-
const resultSection = {
|
|
778
|
+
const resultSection = attachSourceLine({
|
|
750
779
|
type: "lens",
|
|
751
780
|
meta: { title: lens.title || section.title },
|
|
752
|
-
segments,
|
|
753
781
|
sourcePath: lensPath,
|
|
754
782
|
optional: effectiveOptional,
|
|
755
783
|
...(effectiveHide && { hide: true }),
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
contentId: lens.id ?? null,
|
|
759
|
-
tldr: lens.tldr,
|
|
760
|
-
summaryForTutor: lens.summaryForTutor,
|
|
761
|
-
minChatMessages: lens.minChatMessages,
|
|
762
|
-
addToAiContext: lens.addToAiContext,
|
|
763
|
-
...computeSectionStats(segments),
|
|
764
|
-
displayType: computeDisplayType(segments),
|
|
765
|
-
};
|
|
784
|
+
...lensSectionFields(lens, segments, lensPath, section.line, errors),
|
|
785
|
+
}, getSourceLine(lens));
|
|
766
786
|
sections.push(resultSection);
|
|
767
787
|
return { sections, errors };
|
|
768
788
|
}
|
|
@@ -989,7 +1009,10 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
989
1009
|
if (parsedSegment.optional) {
|
|
990
1010
|
segment.optional = true;
|
|
991
1011
|
}
|
|
992
|
-
return {
|
|
1012
|
+
return {
|
|
1013
|
+
segment: attachSourceLine(segment, getSourceLine(parsedSegment)),
|
|
1014
|
+
errors,
|
|
1015
|
+
};
|
|
993
1016
|
}
|
|
994
1017
|
case "chat": {
|
|
995
1018
|
let instructions = parsedSegment.instructions;
|
|
@@ -1013,7 +1036,10 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1013
1036
|
if (parsedSegment.hidePreviousContentFromTutor) {
|
|
1014
1037
|
segment.hidePreviousContentFromTutor = true;
|
|
1015
1038
|
}
|
|
1016
|
-
return {
|
|
1039
|
+
return {
|
|
1040
|
+
segment: attachSourceLine(segment, getSourceLine(parsedSegment)),
|
|
1041
|
+
errors,
|
|
1042
|
+
};
|
|
1017
1043
|
}
|
|
1018
1044
|
case "article": {
|
|
1019
1045
|
// Source comes from the parsed segment (set via inheritance in parseLens)
|
|
@@ -1079,7 +1105,11 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1079
1105
|
// Extract the excerpt
|
|
1080
1106
|
const excerptResult = extractArticleExcerpt(articleContent, parsedSegment.fromAnchor, parsedSegment.toAnchor, articlePath);
|
|
1081
1107
|
if (excerptResult.error) {
|
|
1082
|
-
errors.push({
|
|
1108
|
+
errors.push({
|
|
1109
|
+
...excerptResult.error,
|
|
1110
|
+
file: lensPath,
|
|
1111
|
+
line: getSourceLine(parsedSegment),
|
|
1112
|
+
});
|
|
1083
1113
|
return { segment: null, errors };
|
|
1084
1114
|
}
|
|
1085
1115
|
const segment = {
|
|
@@ -1101,7 +1131,10 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1101
1131
|
if (parsedSegment.optional) {
|
|
1102
1132
|
segment.optional = true;
|
|
1103
1133
|
}
|
|
1104
|
-
return {
|
|
1134
|
+
return {
|
|
1135
|
+
segment: attachSourceLine(segment, getSourceLine(parsedSegment)),
|
|
1136
|
+
errors,
|
|
1137
|
+
};
|
|
1105
1138
|
}
|
|
1106
1139
|
case "video": {
|
|
1107
1140
|
// Source comes from the parsed segment (set via inheritance in parseLens)
|
|
@@ -1180,7 +1213,11 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1180
1213
|
const { fromTime, toTime } = resolveVideoRange(parsedSegment.fromTimeStr, parsedSegment.toTimeStr, vfm);
|
|
1181
1214
|
const excerptResult = extractVideoExcerpt(transcriptContent, fromTime, toTime, videoPath, timestamps);
|
|
1182
1215
|
if (excerptResult.error) {
|
|
1183
|
-
errors.push({
|
|
1216
|
+
errors.push({
|
|
1217
|
+
...excerptResult.error,
|
|
1218
|
+
file: lensPath,
|
|
1219
|
+
line: getSourceLine(parsedSegment),
|
|
1220
|
+
});
|
|
1184
1221
|
return { segment: null, errors };
|
|
1185
1222
|
}
|
|
1186
1223
|
const segment = {
|
|
@@ -1205,7 +1242,10 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1205
1242
|
if (parsedSegment.optional) {
|
|
1206
1243
|
segment.optional = true;
|
|
1207
1244
|
}
|
|
1208
|
-
return {
|
|
1245
|
+
return {
|
|
1246
|
+
segment: attachSourceLine(segment, getSourceLine(parsedSegment)),
|
|
1247
|
+
errors,
|
|
1248
|
+
};
|
|
1209
1249
|
}
|
|
1210
1250
|
case "question": {
|
|
1211
1251
|
let assessmentInstructions = parsedSegment.assessmentInstructions;
|
|
@@ -1235,7 +1275,10 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1235
1275
|
segment.feedback = parsedSegment.feedback;
|
|
1236
1276
|
if (parsedSegment.optional)
|
|
1237
1277
|
segment.optional = true;
|
|
1238
|
-
return {
|
|
1278
|
+
return {
|
|
1279
|
+
segment: attachSourceLine(segment, getSourceLine(parsedSegment)),
|
|
1280
|
+
errors,
|
|
1281
|
+
};
|
|
1239
1282
|
}
|
|
1240
1283
|
case "roleplay": {
|
|
1241
1284
|
let aiInstructions = parsedSegment.aiInstructions;
|
|
@@ -1272,7 +1315,10 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1272
1315
|
segment.optional = true;
|
|
1273
1316
|
if (parsedSegment.feedback)
|
|
1274
1317
|
segment.feedback = true;
|
|
1275
|
-
return {
|
|
1318
|
+
return {
|
|
1319
|
+
segment: attachSourceLine(segment, getSourceLine(parsedSegment)),
|
|
1320
|
+
errors,
|
|
1321
|
+
};
|
|
1276
1322
|
}
|
|
1277
1323
|
case "embed": {
|
|
1278
1324
|
if (!parsedSegment.source) {
|
|
@@ -1343,7 +1389,11 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1343
1389
|
}
|
|
1344
1390
|
const excerptResult = extractArticleExcerpt(articleContent, parsedSegment.fromAnchor, parsedSegment.toAnchor, articlePath);
|
|
1345
1391
|
if (excerptResult.error) {
|
|
1346
|
-
errors.push({
|
|
1392
|
+
errors.push({
|
|
1393
|
+
...excerptResult.error,
|
|
1394
|
+
file: lensPath,
|
|
1395
|
+
line: getSourceLine(parsedSegment),
|
|
1396
|
+
});
|
|
1347
1397
|
return { segment: null, errors };
|
|
1348
1398
|
}
|
|
1349
1399
|
const segment = {
|
|
@@ -1371,7 +1421,10 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1371
1421
|
segment.sandbox = parsedSegment.sandbox;
|
|
1372
1422
|
if (parsedSegment.optional)
|
|
1373
1423
|
segment.optional = true;
|
|
1374
|
-
return {
|
|
1424
|
+
return {
|
|
1425
|
+
segment: attachSourceLine(segment, getSourceLine(parsedSegment)),
|
|
1426
|
+
errors,
|
|
1427
|
+
};
|
|
1375
1428
|
}
|
|
1376
1429
|
default:
|
|
1377
1430
|
return { segment: null, errors };
|
|
@@ -1431,22 +1484,13 @@ export function flattenLens(lensPath, files, tierMap, preParsedLens) {
|
|
|
1431
1484
|
.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
1432
1485
|
}
|
|
1433
1486
|
}
|
|
1434
|
-
const section = {
|
|
1487
|
+
const section = attachSourceLine({
|
|
1435
1488
|
type: "lens",
|
|
1436
1489
|
meta,
|
|
1437
|
-
segments,
|
|
1438
1490
|
sourcePath: lensPath,
|
|
1439
1491
|
optional: false,
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
contentId: lens.id ?? null,
|
|
1443
|
-
tldr: lens.tldr,
|
|
1444
|
-
summaryForTutor: lens.summaryForTutor,
|
|
1445
|
-
minChatMessages: lens.minChatMessages,
|
|
1446
|
-
addToAiContext: lens.addToAiContext,
|
|
1447
|
-
...computeSectionStats(segments),
|
|
1448
|
-
displayType: computeDisplayType(segments),
|
|
1449
|
-
};
|
|
1492
|
+
...lensSectionFields(lens, segments, lensPath, 1, errors),
|
|
1493
|
+
}, getSourceLine(lens));
|
|
1450
1494
|
const flattenedModule = {
|
|
1451
1495
|
slug: "lens/" + fileNameToSlug(lensPath),
|
|
1452
1496
|
title: meta.title ?? fileNameToSlug(lensPath),
|