lens-content-processor 0.2.1 → 0.3.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/video.js +4 -4
- package/dist/bundler/video.js.map +1 -1
- package/dist/cli.d.ts +1 -2
- package/dist/cli.js +11 -9
- package/dist/cli.js.map +1 -1
- package/dist/content-schema.d.ts +34 -0
- package/dist/content-schema.js +62 -0
- package/dist/content-schema.js.map +1 -0
- package/dist/flattener/index.d.ts +21 -1
- package/dist/flattener/index.js +316 -33
- package/dist/flattener/index.js.map +1 -1
- package/dist/fs/read-vault.d.ts +1 -4
- package/dist/fs/read-vault.js +4 -8
- package/dist/fs/read-vault.js.map +1 -1
- package/dist/index.d.ts +25 -2
- package/dist/index.js +231 -6
- package/dist/index.js.map +1 -1
- package/dist/parser/article.d.ts +16 -0
- package/dist/parser/article.js +70 -0
- package/dist/parser/article.js.map +1 -0
- package/dist/parser/course.d.ts +2 -2
- package/dist/parser/course.js +18 -35
- package/dist/parser/course.js.map +1 -1
- package/dist/parser/frontmatter.js +2 -0
- package/dist/parser/frontmatter.js.map +1 -1
- package/dist/parser/learning-outcome.d.ts +4 -2
- package/dist/parser/learning-outcome.js +65 -23
- package/dist/parser/learning-outcome.js.map +1 -1
- package/dist/parser/lens.d.ts +38 -1
- package/dist/parser/lens.js +173 -18
- package/dist/parser/lens.js.map +1 -1
- package/dist/parser/module.d.ts +11 -5
- package/dist/parser/module.js +172 -76
- package/dist/parser/module.js.map +1 -1
- package/dist/parser/sections.js +116 -13
- package/dist/parser/sections.js.map +1 -1
- package/dist/parser/video-transcript.d.ts +11 -0
- package/dist/parser/video-transcript.js +39 -0
- package/dist/parser/video-transcript.js.map +1 -0
- package/dist/parser/wikilink.d.ts +2 -0
- package/dist/parser/wikilink.js +88 -24
- package/dist/parser/wikilink.js.map +1 -1
- package/dist/utils/slug.d.ts +5 -0
- package/dist/utils/slug.js +16 -0
- package/dist/utils/slug.js.map +1 -0
- package/dist/validator/chat-precedence.d.ts +9 -0
- package/dist/validator/chat-precedence.js +32 -0
- package/dist/validator/chat-precedence.js.map +1 -0
- package/dist/validator/duplicates.d.ts +13 -0
- package/dist/validator/duplicates.js +27 -0
- package/dist/validator/duplicates.js.map +1 -0
- package/dist/validator/field-typos.d.ts +11 -0
- package/dist/validator/field-typos.js +36 -28
- package/dist/validator/field-typos.js.map +1 -1
- package/dist/validator/field-values.d.ts +14 -0
- package/dist/validator/field-values.js +61 -7
- package/dist/validator/field-values.js.map +1 -1
- package/dist/validator/output-integrity.d.ts +7 -0
- package/dist/validator/output-integrity.js +57 -0
- package/dist/validator/output-integrity.js.map +1 -0
- package/dist/validator/segment-fields.js +1 -15
- package/dist/validator/segment-fields.js.map +1 -1
- package/dist/validator/tier.d.ts +18 -0
- package/dist/validator/tier.js +74 -0
- package/dist/validator/tier.js.map +1 -0
- package/dist/validator/timestamps.d.ts +2 -0
- package/dist/validator/timestamps.js +91 -0
- package/dist/validator/timestamps.js.map +1 -0
- package/dist/validator/url-reachability.d.ts +8 -0
- package/dist/validator/url-reachability.js +60 -0
- package/dist/validator/url-reachability.js.map +1 -0
- package/dist/validator/validate-frontmatter.d.ts +9 -0
- package/dist/validator/validate-frontmatter.js +53 -0
- package/dist/validator/validate-frontmatter.js.map +1 -0
- package/package.json +5 -5
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { parseFrontmatter } from './frontmatter.js';
|
|
2
|
+
import { validateFrontmatter } from '../validator/validate-frontmatter.js';
|
|
3
|
+
export function parseArticle(content, file) {
|
|
4
|
+
const errors = [];
|
|
5
|
+
const frontmatterResult = parseFrontmatter(content, file);
|
|
6
|
+
if (frontmatterResult.error) {
|
|
7
|
+
errors.push(frontmatterResult.error);
|
|
8
|
+
return { article: null, errors };
|
|
9
|
+
}
|
|
10
|
+
const { frontmatter } = frontmatterResult;
|
|
11
|
+
// Validate frontmatter against schema (typo detection + required fields)
|
|
12
|
+
const frontmatterErrors = validateFrontmatter(frontmatter, 'article', file);
|
|
13
|
+
errors.push(...frontmatterErrors);
|
|
14
|
+
const hasRequiredError = frontmatterErrors.some(e => e.severity === 'error');
|
|
15
|
+
if (hasRequiredError) {
|
|
16
|
+
return { article: null, errors };
|
|
17
|
+
}
|
|
18
|
+
// Check text fields for wikilinks (not source_url — that's a URL)
|
|
19
|
+
const textFields = ['title', 'author'];
|
|
20
|
+
for (const field of textFields) {
|
|
21
|
+
const raw = frontmatter[field];
|
|
22
|
+
const values = Array.isArray(raw) ? raw.map(String) : [String(raw)];
|
|
23
|
+
if (values.some(v => /\[\[.+?\]\]/.test(v))) {
|
|
24
|
+
errors.push({
|
|
25
|
+
file,
|
|
26
|
+
line: 2,
|
|
27
|
+
message: `Field '${field}' contains a wikilink — use plain text`,
|
|
28
|
+
suggestion: `Remove [[...]] from '${field}'`,
|
|
29
|
+
severity: 'error',
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const { body, bodyStartLine } = frontmatterResult;
|
|
34
|
+
// Scan body for images
|
|
35
|
+
const imageUrls = [];
|
|
36
|
+
const bodyLines = body.split('\n');
|
|
37
|
+
for (let i = 0; i < bodyLines.length; i++) {
|
|
38
|
+
const line = bodyLines[i];
|
|
39
|
+
const absoluteLine = bodyStartLine + i;
|
|
40
|
+
// Detect wiki-link images: ![[...]]
|
|
41
|
+
const wikiImagePattern = /!\[\[([^\]]+)\]\]/g;
|
|
42
|
+
let wikiMatch;
|
|
43
|
+
while ((wikiMatch = wikiImagePattern.exec(line)) !== null) {
|
|
44
|
+
errors.push({
|
|
45
|
+
file,
|
|
46
|
+
line: absoluteLine,
|
|
47
|
+
message: `Wiki-link image not supported: ![[${wikiMatch[1]}]]`,
|
|
48
|
+
suggestion: 'Use standard markdown image syntax: ',
|
|
49
|
+
severity: 'error',
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// Collect standard markdown images:  or 
|
|
53
|
+
const mdImagePattern = /!\[([^\]]*)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g;
|
|
54
|
+
let mdMatch;
|
|
55
|
+
while ((mdMatch = mdImagePattern.exec(line)) !== null) {
|
|
56
|
+
imageUrls.push({ url: mdMatch[2], line: absoluteLine });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const article = {
|
|
60
|
+
title: String(frontmatter.title),
|
|
61
|
+
author: Array.isArray(frontmatter.author)
|
|
62
|
+
? frontmatter.author.join(', ')
|
|
63
|
+
: String(frontmatter.author),
|
|
64
|
+
sourceUrl: String(frontmatter.source_url),
|
|
65
|
+
date: frontmatter.date !== undefined ? String(frontmatter.date) : undefined,
|
|
66
|
+
imageUrls,
|
|
67
|
+
};
|
|
68
|
+
return { article, errors };
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=article.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"article.js","sourceRoot":"","sources":["../../src/parser/article.ts"],"names":[],"mappings":"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"}
|
package/dist/parser/course.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export interface CourseParseResult {
|
|
|
11
11
|
* - `# Module: [[../modules/name.md|Display]]` - references a module
|
|
12
12
|
* - `# Meeting: 1` - marks a meeting point
|
|
13
13
|
*
|
|
14
|
-
* The
|
|
15
|
-
*
|
|
14
|
+
* The raw wikilink path is stored in the progression item; processContent
|
|
15
|
+
* resolves it to the frontmatter slug after all files are parsed.
|
|
16
16
|
*/
|
|
17
17
|
export declare function parseCourse(content: string, file: string): CourseParseResult;
|
package/dist/parser/course.js
CHANGED
|
@@ -1,19 +1,12 @@
|
|
|
1
1
|
import { parseFrontmatter } from './frontmatter.js';
|
|
2
2
|
import { parseSections } from './sections.js';
|
|
3
3
|
import { parseWikilink } from './wikilink.js';
|
|
4
|
-
import {
|
|
4
|
+
import { validateSlugFormat } from '../validator/field-values.js';
|
|
5
|
+
import { validateFrontmatter } from '../validator/validate-frontmatter.js';
|
|
5
6
|
// Valid section types for course files
|
|
6
7
|
export const COURSE_SECTION_TYPES = new Set(['module', 'meeting']);
|
|
7
8
|
/**
|
|
8
|
-
*
|
|
9
|
-
* e.g., '../modules/intro.md' -> 'intro'
|
|
10
|
-
*/
|
|
11
|
-
function extractSlugFromPath(path) {
|
|
12
|
-
const filename = basename(path);
|
|
13
|
-
return filename.replace(/\.md$/, '');
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Parses a Module section title to extract the wikilink and module slug
|
|
9
|
+
* Parses a Module section title to extract the wikilink path
|
|
17
10
|
* Title format: [[../modules/intro.md|Display Text]]
|
|
18
11
|
*/
|
|
19
12
|
function parseModuleSection(section, file) {
|
|
@@ -30,9 +23,8 @@ function parseModuleSection(section, file) {
|
|
|
30
23
|
},
|
|
31
24
|
};
|
|
32
25
|
}
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
return { slug, optional };
|
|
26
|
+
const optional = section.fields.optional?.toLowerCase() === 'true';
|
|
27
|
+
return { path: wikilink.path, optional };
|
|
36
28
|
}
|
|
37
29
|
/**
|
|
38
30
|
* Parses a Meeting section title to extract the meeting number
|
|
@@ -60,8 +52,8 @@ function parseMeetingSection(section, file) {
|
|
|
60
52
|
* - `# Module: [[../modules/name.md|Display]]` - references a module
|
|
61
53
|
* - `# Meeting: 1` - marks a meeting point
|
|
62
54
|
*
|
|
63
|
-
* The
|
|
64
|
-
*
|
|
55
|
+
* The raw wikilink path is stored in the progression item; processContent
|
|
56
|
+
* resolves it to the frontmatter slug after all files are parsed.
|
|
65
57
|
*/
|
|
66
58
|
export function parseCourse(content, file) {
|
|
67
59
|
const errors = [];
|
|
@@ -72,26 +64,17 @@ export function parseCourse(content, file) {
|
|
|
72
64
|
return { course: null, errors };
|
|
73
65
|
}
|
|
74
66
|
const { frontmatter, body, bodyStartLine } = frontmatterResult;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
if (!frontmatter.title) {
|
|
86
|
-
errors.push({
|
|
87
|
-
file,
|
|
88
|
-
line: 2,
|
|
89
|
-
message: 'Missing required field: title',
|
|
90
|
-
suggestion: "Add 'title: Your Course Title' to frontmatter",
|
|
91
|
-
severity: 'error',
|
|
92
|
-
});
|
|
67
|
+
const frontmatterErrors = validateFrontmatter(frontmatter, 'course', file);
|
|
68
|
+
errors.push(...frontmatterErrors);
|
|
69
|
+
// Course-specific: validate slug format
|
|
70
|
+
const slug = frontmatter.slug;
|
|
71
|
+
if (typeof slug === 'string' && slug.trim() !== '') {
|
|
72
|
+
const slugFormatError = validateSlugFormat(slug, file, 2);
|
|
73
|
+
if (slugFormatError) {
|
|
74
|
+
errors.push(slugFormatError);
|
|
75
|
+
}
|
|
93
76
|
}
|
|
94
|
-
if (errors.
|
|
77
|
+
if (errors.some(e => e.severity === 'error')) {
|
|
95
78
|
return { course: null, errors };
|
|
96
79
|
}
|
|
97
80
|
// Parse sections (H1 headers for course files)
|
|
@@ -117,7 +100,7 @@ export function parseCourse(content, file) {
|
|
|
117
100
|
else {
|
|
118
101
|
progression.push({
|
|
119
102
|
type: 'module',
|
|
120
|
-
|
|
103
|
+
path: result.path,
|
|
121
104
|
optional: result.optional,
|
|
122
105
|
});
|
|
123
106
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"course.js","sourceRoot":"","sources":["../../src/parser/course.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAsB,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"course.js","sourceRoot":"","sources":["../../src/parser/course.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,8 @@ import { parse as parseYaml } from 'yaml';
|
|
|
3
3
|
// Matches: ---\n<yaml>\n---\n<body>
|
|
4
4
|
const FRONTMATTER_PATTERN = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/;
|
|
5
5
|
export function parseFrontmatter(content, file = '') {
|
|
6
|
+
// Normalize Windows line endings
|
|
7
|
+
content = content.replace(/\r\n/g, '\n');
|
|
6
8
|
const match = content.match(FRONTMATTER_PATTERN);
|
|
7
9
|
if (!match) {
|
|
8
10
|
// Check if it starts with --- but doesn't close
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/parser/frontmatter.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAU1C,oCAAoC;AACpC,MAAM,mBAAmB,GAAG,oCAAoC,CAAC;AAEjE,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,OAAe,EAAE;IACjE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAEjD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,gDAAgD;QAChD,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAChE,OAAO;gBACL,WAAW,EAAE,EAAE;gBACf,IAAI,EAAE,OAAO;gBACb,aAAa,EAAE,CAAC;gBAChB,KAAK,EAAE;oBACL,IAAI;oBACJ,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,4CAA4C;oBACrD,UAAU,EAAE,kDAAkD;oBAC9D,QAAQ,EAAE,OAAO;iBAClB;aACF,CAAC;QACJ,CAAC;QACD,OAAO;YACL,WAAW,EAAE,EAAE;YACf,IAAI,EAAE,OAAO;YACb,aAAa,EAAE,CAAC;YAChB,KAAK,EAAE;gBACL,IAAI;gBACJ,IAAI,EAAE,CAAC;gBACP,OAAO,EAAE,qBAAqB;gBAC9B,UAAU,EAAE,qDAAqD;gBACjE,QAAQ,EAAE,OAAO;aAClB;SACF,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,mDAAmD;IAE7G,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QACjD,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;IAC9C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO;YACL,WAAW,EAAE,EAAE;YACf,IAAI;YACJ,aAAa;YACb,KAAK,EAAE;gBACL,IAAI;gBACJ,IAAI,EAAE,CAAC;gBACP,OAAO,EAAE,iBAAiB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;gBACtE,UAAU,EAAE,kDAAkD;gBAC9D,QAAQ,EAAE,OAAO;aAClB;SACF,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/parser/frontmatter.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAU1C,oCAAoC;AACpC,MAAM,mBAAmB,GAAG,oCAAoC,CAAC;AAEjE,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,OAAe,EAAE;IACjE,iCAAiC;IACjC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAEzC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAEjD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,gDAAgD;QAChD,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAChE,OAAO;gBACL,WAAW,EAAE,EAAE;gBACf,IAAI,EAAE,OAAO;gBACb,aAAa,EAAE,CAAC;gBAChB,KAAK,EAAE;oBACL,IAAI;oBACJ,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,4CAA4C;oBACrD,UAAU,EAAE,kDAAkD;oBAC9D,QAAQ,EAAE,OAAO;iBAClB;aACF,CAAC;QACJ,CAAC;QACD,OAAO;YACL,WAAW,EAAE,EAAE;YACf,IAAI,EAAE,OAAO;YACb,aAAa,EAAE,CAAC;YAChB,KAAK,EAAE;gBACL,IAAI;gBACJ,IAAI,EAAE,CAAC;gBACP,OAAO,EAAE,qBAAqB;gBAC9B,UAAU,EAAE,qDAAqD;gBACjE,QAAQ,EAAE,OAAO;aAClB;SACF,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,mDAAmD;IAE7G,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QACjD,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;IAC9C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO;YACL,WAAW,EAAE,EAAE;YACf,IAAI;YACJ,aAAa;YACb,KAAK,EAAE;gBACL,IAAI;gBACJ,IAAI,EAAE,CAAC;gBACP,OAAO,EAAE,iBAAiB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;gBACtE,UAAU,EAAE,kDAAkD;gBAC9D,QAAQ,EAAE,OAAO;aAClB;SACF,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { ContentError } from '../index.js';
|
|
2
|
+
import { type ParsedLensSegment } from './lens.js';
|
|
2
3
|
export interface ParsedLensRef {
|
|
3
4
|
source: string;
|
|
4
5
|
resolvedPath: string;
|
|
5
6
|
optional: boolean;
|
|
6
7
|
}
|
|
7
8
|
export interface ParsedTestRef {
|
|
8
|
-
source
|
|
9
|
-
resolvedPath
|
|
9
|
+
source?: string;
|
|
10
|
+
resolvedPath?: string;
|
|
11
|
+
segments: ParsedLensSegment[];
|
|
10
12
|
}
|
|
11
13
|
export interface ParsedLearningOutcome {
|
|
12
14
|
id: string;
|
|
@@ -2,8 +2,12 @@ import { parseFrontmatter } from './frontmatter.js';
|
|
|
2
2
|
import { parseSections, LO_SECTION_TYPES } from './sections.js';
|
|
3
3
|
import { parseWikilink, resolveWikilinkPath, hasRelativePath } from './wikilink.js';
|
|
4
4
|
import { detectFieldTypos } from '../validator/field-typos.js';
|
|
5
|
+
import { validateFrontmatter } from '../validator/validate-frontmatter.js';
|
|
6
|
+
import { parseSegments, convertSegment, stripObsidianComments } from './lens.js';
|
|
5
7
|
export function parseLearningOutcome(content, file) {
|
|
6
8
|
const errors = [];
|
|
9
|
+
// Strip Obsidian comments before parsing
|
|
10
|
+
content = stripObsidianComments(content);
|
|
7
11
|
// Step 1: Parse frontmatter and validate id field
|
|
8
12
|
const frontmatterResult = parseFrontmatter(content, file);
|
|
9
13
|
if (frontmatterResult.error) {
|
|
@@ -11,13 +15,18 @@ export function parseLearningOutcome(content, file) {
|
|
|
11
15
|
return { learningOutcome: null, errors };
|
|
12
16
|
}
|
|
13
17
|
const { frontmatter, body, bodyStartLine } = frontmatterResult;
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
const frontmatterErrors = validateFrontmatter(frontmatter, 'learning-outcome', file);
|
|
19
|
+
errors.push(...frontmatterErrors);
|
|
20
|
+
if (frontmatterErrors.some(e => e.severity === 'error')) {
|
|
21
|
+
return { learningOutcome: null, errors };
|
|
22
|
+
}
|
|
23
|
+
// LO-specific: id must be a string
|
|
24
|
+
if (typeof frontmatter.id !== 'string') {
|
|
16
25
|
errors.push({
|
|
17
26
|
file,
|
|
18
27
|
line: 2,
|
|
19
|
-
message: '
|
|
20
|
-
suggestion: "
|
|
28
|
+
message: `Field 'id' must be a string, got ${typeof frontmatter.id}`,
|
|
29
|
+
suggestion: "Use quotes: id: '12345'",
|
|
21
30
|
severity: 'error',
|
|
22
31
|
});
|
|
23
32
|
return { learningOutcome: null, errors };
|
|
@@ -55,12 +64,17 @@ export function parseLearningOutcome(content, file) {
|
|
|
55
64
|
}
|
|
56
65
|
// Parse wikilink and resolve path
|
|
57
66
|
const wikilink = parseWikilink(source);
|
|
58
|
-
if (!wikilink) {
|
|
67
|
+
if (!wikilink || wikilink.error) {
|
|
68
|
+
const suggestion = wikilink?.correctedPath
|
|
69
|
+
? `Did you mean '[[${wikilink.correctedPath}]]'?`
|
|
70
|
+
: 'Use format [[../Lenses/filename.md|Display Text]]';
|
|
59
71
|
errors.push({
|
|
60
72
|
file,
|
|
61
73
|
line: section.line,
|
|
62
|
-
message:
|
|
63
|
-
|
|
74
|
+
message: wikilink?.error
|
|
75
|
+
? `${wikilink.error} in source:: field: ${source}`
|
|
76
|
+
: `Invalid wikilink format in source:: field: ${source}`,
|
|
77
|
+
suggestion,
|
|
64
78
|
severity: 'error',
|
|
65
79
|
});
|
|
66
80
|
continue;
|
|
@@ -77,7 +91,7 @@ export function parseLearningOutcome(content, file) {
|
|
|
77
91
|
continue;
|
|
78
92
|
}
|
|
79
93
|
const resolvedPath = resolveWikilinkPath(wikilink.path, file);
|
|
80
|
-
const optional = section.fields.optional === 'true';
|
|
94
|
+
const optional = section.fields.optional?.toLowerCase() === 'true';
|
|
81
95
|
lenses.push({
|
|
82
96
|
source,
|
|
83
97
|
resolvedPath,
|
|
@@ -86,26 +100,54 @@ export function parseLearningOutcome(content, file) {
|
|
|
86
100
|
}
|
|
87
101
|
else if (section.type === 'test') {
|
|
88
102
|
const source = section.fields.source;
|
|
89
|
-
|
|
90
|
-
if (
|
|
91
|
-
|
|
103
|
+
let resolvedPath;
|
|
104
|
+
if (source) {
|
|
105
|
+
// Parse wikilink and resolve path
|
|
106
|
+
const wikilink = parseWikilink(source);
|
|
107
|
+
if (!wikilink || wikilink.error) {
|
|
108
|
+
const suggestion = wikilink?.correctedPath
|
|
109
|
+
? `Did you mean '[[${wikilink.correctedPath}]]'?`
|
|
110
|
+
: 'Use format [[../Tests/filename.md|Display Text]]';
|
|
111
|
+
errors.push({
|
|
112
|
+
file,
|
|
113
|
+
line: section.line,
|
|
114
|
+
message: wikilink?.error
|
|
115
|
+
? `${wikilink.error} in source:: field: ${source}`
|
|
116
|
+
: `Invalid wikilink format in source:: field: ${source}`,
|
|
117
|
+
suggestion,
|
|
118
|
+
severity: 'error',
|
|
119
|
+
});
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
resolvedPath = resolveWikilinkPath(wikilink.path, file);
|
|
92
123
|
}
|
|
93
|
-
// Parse
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
line
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
124
|
+
// Parse inline H4 segments (#### Question, #### Chat, #### Text) from body
|
|
125
|
+
const { segments: rawSegments, errors: segmentErrors } = parseSegments(section.body, section.line + 1, file);
|
|
126
|
+
// Adjust segment error line numbers for frontmatter offset
|
|
127
|
+
for (const err of segmentErrors) {
|
|
128
|
+
if (err.line) {
|
|
129
|
+
err.line += bodyStartLine - 1;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
errors.push(...segmentErrors);
|
|
133
|
+
const testSegments = [];
|
|
134
|
+
for (const rawSeg of rawSegments) {
|
|
135
|
+
const { segment, errors: conversionErrors } = convertSegment(rawSeg, 'page', file);
|
|
136
|
+
// Adjust conversion error line numbers for frontmatter offset
|
|
137
|
+
for (const err of conversionErrors) {
|
|
138
|
+
if (err.line) {
|
|
139
|
+
err.line += bodyStartLine - 1;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
errors.push(...conversionErrors);
|
|
143
|
+
if (segment) {
|
|
144
|
+
testSegments.push(segment);
|
|
145
|
+
}
|
|
104
146
|
}
|
|
105
|
-
const resolvedPath = resolveWikilinkPath(wikilink.path, file);
|
|
106
147
|
testRef = {
|
|
107
148
|
source,
|
|
108
149
|
resolvedPath,
|
|
150
|
+
segments: testSegments,
|
|
109
151
|
};
|
|
110
152
|
}
|
|
111
153
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"learning-outcome.js","sourceRoot":"","sources":["../../src/parser/learning-outcome.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"learning-outcome.js","sourceRoot":"","sources":["../../src/parser/learning-outcome.ts"],"names":[],"mappings":"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"}
|
package/dist/parser/lens.d.ts
CHANGED
|
@@ -24,7 +24,17 @@ export interface ParsedVideoExcerptSegment {
|
|
|
24
24
|
toTimeStr: string;
|
|
25
25
|
optional?: boolean;
|
|
26
26
|
}
|
|
27
|
-
export
|
|
27
|
+
export interface ParsedQuestionSegment {
|
|
28
|
+
type: 'question';
|
|
29
|
+
content: string;
|
|
30
|
+
assessmentInstructions?: string;
|
|
31
|
+
maxTime?: string;
|
|
32
|
+
maxChars?: number;
|
|
33
|
+
enforceVoice?: boolean;
|
|
34
|
+
optional?: boolean;
|
|
35
|
+
feedback?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export type ParsedLensSegment = ParsedTextSegment | ParsedChatSegment | ParsedArticleExcerptSegment | ParsedVideoExcerptSegment | ParsedQuestionSegment;
|
|
28
38
|
export interface ParsedLensSection {
|
|
29
39
|
type: string;
|
|
30
40
|
title: string;
|
|
@@ -41,6 +51,32 @@ export interface LensParseResult {
|
|
|
41
51
|
lens: ParsedLens | null;
|
|
42
52
|
errors: ContentError[];
|
|
43
53
|
}
|
|
54
|
+
interface RawSegment {
|
|
55
|
+
type: string;
|
|
56
|
+
title?: string;
|
|
57
|
+
fields: Record<string, string>;
|
|
58
|
+
line: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Parse H4 segments from a section body.
|
|
62
|
+
* Segments are defined by `#### <type>` headers within a section.
|
|
63
|
+
*/
|
|
64
|
+
export declare function parseSegments(sectionBody: string, bodyStartLine: number, file: string): {
|
|
65
|
+
segments: RawSegment[];
|
|
66
|
+
errors: ContentError[];
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Convert a raw segment to a typed ParsedLensSegment.
|
|
70
|
+
*/
|
|
71
|
+
export declare function convertSegment(raw: RawSegment, sectionType: string, file: string): {
|
|
72
|
+
segment: ParsedLensSegment | null;
|
|
73
|
+
errors: ContentError[];
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Strip Obsidian %% comments %% from content.
|
|
77
|
+
* Handles both inline (%% ... %% on same line) and block (multiline) comments.
|
|
78
|
+
*/
|
|
79
|
+
export declare function stripObsidianComments(content: string): string;
|
|
44
80
|
/**
|
|
45
81
|
* Parse a lens file into structured lens data.
|
|
46
82
|
*
|
|
@@ -49,3 +85,4 @@ export interface LensParseResult {
|
|
|
49
85
|
* - H4 (`####`) for segments: Text, Chat, Article-excerpt, Video-excerpt
|
|
50
86
|
*/
|
|
51
87
|
export declare function parseLens(content: string, file: string): LensParseResult;
|
|
88
|
+
export {};
|