mr-md 1.0.1 → 1.0.2
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/renderer/blocks.d.ts +2 -2
- package/dist/renderer/blocks.d.ts.map +1 -1
- package/dist/renderer/blocks.js +14 -9
- package/dist/renderer/index.js +3 -3
- package/dist/renderer/markdown.d.ts +5 -0
- package/dist/renderer/markdown.d.ts.map +1 -1
- package/dist/renderer/markdown.js +13 -2
- package/package.json +1 -1
- package/src/renderer/blocks.ts +13 -8
- package/src/renderer/index.ts +3 -3
- package/src/renderer/markdown.ts +16 -3
|
@@ -5,11 +5,11 @@ export declare function escHtml(str: string): string;
|
|
|
5
5
|
export declare function escAttr(str: string): string;
|
|
6
6
|
declare function renderBlock(block: Block, idx: number, options: BuildOptions): {
|
|
7
7
|
html: string;
|
|
8
|
-
|
|
8
|
+
navItems?: NavItem[];
|
|
9
9
|
};
|
|
10
10
|
declare function renderBlockInner(block: Block, idx: number, options: BuildOptions): {
|
|
11
11
|
html: string;
|
|
12
|
-
|
|
12
|
+
navItems?: NavItem[];
|
|
13
13
|
};
|
|
14
14
|
export { blockChrome, renderBlock, renderBlockInner };
|
|
15
15
|
//# sourceMappingURL=blocks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../src/renderer/blocks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAA0B,MAAM,aAAa,CAAC;AAC/E,OAAO,EACN,WAAW,EAKX,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,KAAK,OAAO,EAAmC,MAAM,YAAY,CAAC;AAG3E,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO3C;AACD,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C;AAID,iBAAS,WAAW,CACnB,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,YAAY,GACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,
|
|
1
|
+
{"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../src/renderer/blocks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAA0B,MAAM,aAAa,CAAC;AAC/E,OAAO,EACN,WAAW,EAKX,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,KAAK,OAAO,EAAmC,MAAM,YAAY,CAAC;AAG3E,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO3C;AACD,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C;AAID,iBAAS,WAAW,CACnB,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,YAAY,GACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;CAAE,CAuBxC;AAED,iBAAS,gBAAgB,CACxB,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,YAAY,GACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;CAAE,CA0QxC;AAuID,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAAC"}
|
package/dist/renderer/blocks.js
CHANGED
|
@@ -42,13 +42,18 @@ function renderBlockInner(block, idx, options) {
|
|
|
42
42
|
const id = `heading-${idx}`;
|
|
43
43
|
return {
|
|
44
44
|
html: `<section id="${id}" class="bk-section bk-heading">${html}</section>`,
|
|
45
|
-
|
|
45
|
+
navItems: [{ id, label, kind: "heading" }],
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
case "markdown": {
|
|
49
49
|
const md = resolveContent(block.src, options, "md");
|
|
50
|
-
const { html } = mdToHtml(md);
|
|
51
|
-
|
|
50
|
+
const { html, headings } = mdToHtml(md);
|
|
51
|
+
const navItems = headings.map(h => ({
|
|
52
|
+
id: h.id,
|
|
53
|
+
label: h.text,
|
|
54
|
+
kind: h.level === 2 ? "heading" : "section"
|
|
55
|
+
}));
|
|
56
|
+
return { html: `<div class="bk-markdown">${html}</div>`, navItems: navItems.length > 0 ? navItems : undefined };
|
|
52
57
|
}
|
|
53
58
|
case "section": {
|
|
54
59
|
const md = resolveContent(block.src, options, "md");
|
|
@@ -57,7 +62,7 @@ function renderBlockInner(block, idx, options) {
|
|
|
57
62
|
const id = `section-${idx}`;
|
|
58
63
|
return {
|
|
59
64
|
html: `<section id="${id}" class="bk-section bk-subsection">${html}</section>`,
|
|
60
|
-
|
|
65
|
+
navItems: [{ id, label, kind: "section" }],
|
|
61
66
|
};
|
|
62
67
|
}
|
|
63
68
|
case "important":
|
|
@@ -227,11 +232,11 @@ function renderBlockInner(block, idx, options) {
|
|
|
227
232
|
${quiz.questions.map((q, qi) => renderQuestion(q, `quiz-${idx}`, qi)).join("\n")}
|
|
228
233
|
</div>
|
|
229
234
|
</div>`,
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
+
navItems: [{
|
|
236
|
+
id: `quiz-${idx}`,
|
|
237
|
+
label: block.label ?? "Questions",
|
|
238
|
+
kind: "quiz",
|
|
239
|
+
}],
|
|
235
240
|
};
|
|
236
241
|
}
|
|
237
242
|
case "divider":
|
package/dist/renderer/index.js
CHANGED
|
@@ -5,10 +5,10 @@ export function render(lesson, opts = {}) {
|
|
|
5
5
|
const bodyItems = [];
|
|
6
6
|
const structuredNavItems = [];
|
|
7
7
|
lesson.blocks.forEach((block, idx) => {
|
|
8
|
-
const { html,
|
|
8
|
+
const { html, navItems } = renderBlock(block, idx, opts);
|
|
9
9
|
bodyItems.push(html);
|
|
10
|
-
if (
|
|
11
|
-
structuredNavItems.push(
|
|
10
|
+
if (navItems) {
|
|
11
|
+
structuredNavItems.push(...navItems);
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
14
|
return renderPage(lesson, structuredNavItems, bodyItems.join("\n"), opts);
|
|
@@ -2,6 +2,11 @@ import type { Block } from "../types.js";
|
|
|
2
2
|
declare function mdToHtml(md: string): {
|
|
3
3
|
html: string;
|
|
4
4
|
title: string;
|
|
5
|
+
headings: {
|
|
6
|
+
id: string;
|
|
7
|
+
text: string;
|
|
8
|
+
level: number;
|
|
9
|
+
}[];
|
|
5
10
|
};
|
|
6
11
|
declare function blockChrome(kind: string, label: string | undefined, caption: string | undefined, body: string, accent?: string, allowMaximize?: boolean): string;
|
|
7
12
|
declare function mdInline(text: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/renderer/markdown.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAYzC,iBAAS,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/renderer/markdown.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAYzC,iBAAS,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAmFtH;AAeD,iBAAS,WAAW,CACnB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,IAAI,EAAE,MAAM,EACZ,MAAM,SAAY,EAClB,aAAa,UAAO,GAClB,MAAM,CAYR;AAED,iBAAS,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmBtC;AAED,iBAAS,wBAAwB,CAChC,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC,GAC3C,MAAM,CAiCR;AAED,iBAAS,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAIhD;AAED,OAAO,EACN,WAAW,EACX,gBAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,wBAAwB,GACxB,CAAC"}
|
|
@@ -41,7 +41,18 @@ function mdToHtml(md) {
|
|
|
41
41
|
codeBlocks.forEach((match, id) => {
|
|
42
42
|
processedMd = processedMd.replace(`@@BK_CODE_${id}@@`, () => match);
|
|
43
43
|
});
|
|
44
|
-
|
|
44
|
+
const headings = [];
|
|
45
|
+
let headingIdCounter = 0;
|
|
46
|
+
const renderer = new marked.Renderer();
|
|
47
|
+
renderer.heading = ({ tokens, depth, text }) => {
|
|
48
|
+
const id = `bk-heading-${headingIdCounter++}`;
|
|
49
|
+
if (depth === 2 || depth === 3) {
|
|
50
|
+
const plainText = text.replace(/<[^>]+>/g, "");
|
|
51
|
+
headings.push({ id, text: plainText, level: depth });
|
|
52
|
+
}
|
|
53
|
+
return `<h${depth} id="${id}" class="bk-heading-${depth}">${text}</h${depth}>`;
|
|
54
|
+
};
|
|
55
|
+
let html = marked.parse(processedMd, { renderer });
|
|
45
56
|
// Restore math
|
|
46
57
|
mathBlocks.forEach((tex, id) => {
|
|
47
58
|
const rendered = katex.renderToString(tex, {
|
|
@@ -60,7 +71,7 @@ function mdToHtml(md) {
|
|
|
60
71
|
});
|
|
61
72
|
html = html.replace(`@@BK_MATH_INLINE_${id}@@`, () => rendered);
|
|
62
73
|
});
|
|
63
|
-
return { html, title };
|
|
74
|
+
return { html, title, headings };
|
|
64
75
|
}
|
|
65
76
|
function escHtml(s) {
|
|
66
77
|
return s
|
package/package.json
CHANGED
package/src/renderer/blocks.ts
CHANGED
|
@@ -29,7 +29,7 @@ function renderBlock(
|
|
|
29
29
|
block: Block,
|
|
30
30
|
idx: number,
|
|
31
31
|
options: BuildOptions,
|
|
32
|
-
): { html: string;
|
|
32
|
+
): { html: string; navItems?: NavItem[] } {
|
|
33
33
|
try {
|
|
34
34
|
const result = renderBlockInner(block, idx, options);
|
|
35
35
|
if (
|
|
@@ -58,7 +58,7 @@ function renderBlockInner(
|
|
|
58
58
|
block: Block,
|
|
59
59
|
idx: number,
|
|
60
60
|
options: BuildOptions,
|
|
61
|
-
): { html: string;
|
|
61
|
+
): { html: string; navItems?: NavItem[] } {
|
|
62
62
|
switch (block.type) {
|
|
63
63
|
case "heading": {
|
|
64
64
|
const md = resolveContent(block.src, options, "md");
|
|
@@ -67,14 +67,19 @@ function renderBlockInner(
|
|
|
67
67
|
const id = `heading-${idx}`;
|
|
68
68
|
return {
|
|
69
69
|
html: `<section id="${id}" class="bk-section bk-heading">${html}</section>`,
|
|
70
|
-
|
|
70
|
+
navItems: [{ id, label, kind: "heading" }],
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
case "markdown": {
|
|
75
75
|
const md = resolveContent(block.src, options, "md");
|
|
76
|
-
const { html } = mdToHtml(md);
|
|
77
|
-
|
|
76
|
+
const { html, headings } = mdToHtml(md);
|
|
77
|
+
const navItems: NavItem[] = headings.map(h => ({
|
|
78
|
+
id: h.id,
|
|
79
|
+
label: h.text,
|
|
80
|
+
kind: h.level === 2 ? "heading" : "section"
|
|
81
|
+
}));
|
|
82
|
+
return { html: `<div class="bk-markdown">${html}</div>`, navItems: navItems.length > 0 ? navItems : undefined };
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
case "section": {
|
|
@@ -84,7 +89,7 @@ function renderBlockInner(
|
|
|
84
89
|
const id = `section-${idx}`;
|
|
85
90
|
return {
|
|
86
91
|
html: `<section id="${id}" class="bk-section bk-subsection">${html}</section>`,
|
|
87
|
-
|
|
92
|
+
navItems: [{ id, label, kind: "section" }],
|
|
88
93
|
};
|
|
89
94
|
}
|
|
90
95
|
|
|
@@ -305,11 +310,11 @@ function renderBlockInner(
|
|
|
305
310
|
${quiz.questions.map((q, qi) => renderQuestion(q, `quiz-${idx}`, qi)).join("\n")}
|
|
306
311
|
</div>
|
|
307
312
|
</div>`,
|
|
308
|
-
|
|
313
|
+
navItems: [{
|
|
309
314
|
id: `quiz-${idx}`,
|
|
310
315
|
label: block.label ?? "Questions",
|
|
311
316
|
kind: "quiz",
|
|
312
|
-
},
|
|
317
|
+
}],
|
|
313
318
|
};
|
|
314
319
|
}
|
|
315
320
|
|
package/src/renderer/index.ts
CHANGED
|
@@ -10,10 +10,10 @@ export function render(lesson: Lesson, opts: BuildOptions = {}): string {
|
|
|
10
10
|
const structuredNavItems: NavItem[] = [];
|
|
11
11
|
|
|
12
12
|
lesson.blocks.forEach((block, idx) => {
|
|
13
|
-
const { html,
|
|
13
|
+
const { html, navItems } = renderBlock(block, idx, opts);
|
|
14
14
|
bodyItems.push(html);
|
|
15
|
-
if (
|
|
16
|
-
structuredNavItems.push(
|
|
15
|
+
if (navItems) {
|
|
16
|
+
structuredNavItems.push(...navItems);
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
19
|
|
package/src/renderer/markdown.ts
CHANGED
|
@@ -14,7 +14,7 @@ marked.use(markedHighlight({
|
|
|
14
14
|
|
|
15
15
|
// ─── Markdown Rendering (using Marked + KaTeX) ───────────────────────────────
|
|
16
16
|
|
|
17
|
-
function mdToHtml(md: string): { html: string; title: string } {
|
|
17
|
+
function mdToHtml(md: string): { html: string; title: string; headings: { id: string; text: string; level: number }[] } {
|
|
18
18
|
let title = "";
|
|
19
19
|
|
|
20
20
|
// Extract first H1 or H2 as title
|
|
@@ -55,7 +55,20 @@ function mdToHtml(md: string): { html: string; title: string } {
|
|
|
55
55
|
processedMd = processedMd.replace(`@@BK_CODE_${id}@@`, () => match);
|
|
56
56
|
});
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
const headings: { id: string; text: string; level: number }[] = [];
|
|
59
|
+
let headingIdCounter = 0;
|
|
60
|
+
|
|
61
|
+
const renderer = new marked.Renderer();
|
|
62
|
+
renderer.heading = ({ tokens, depth, text }) => {
|
|
63
|
+
const id = `bk-heading-${headingIdCounter++}`;
|
|
64
|
+
if (depth === 2 || depth === 3) {
|
|
65
|
+
const plainText = text.replace(/<[^>]+>/g, "");
|
|
66
|
+
headings.push({ id, text: plainText, level: depth });
|
|
67
|
+
}
|
|
68
|
+
return `<h${depth} id="${id}" class="bk-heading-${depth}">${text}</h${depth}>`;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
let html = marked.parse(processedMd, { renderer }) as string;
|
|
59
72
|
|
|
60
73
|
// Restore math
|
|
61
74
|
mathBlocks.forEach((tex, id) => {
|
|
@@ -83,7 +96,7 @@ function mdToHtml(md: string): { html: string; title: string } {
|
|
|
83
96
|
html = html.replace(`@@BK_MATH_INLINE_${id}@@`, () => rendered);
|
|
84
97
|
});
|
|
85
98
|
|
|
86
|
-
return { html, title };
|
|
99
|
+
return { html, title, headings };
|
|
87
100
|
}
|
|
88
101
|
|
|
89
102
|
function escHtml(s: string): string {
|