@mulmocast/slide 0.1.6 → 0.1.7
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/README.md +42 -0
- package/lib/actions/bundle.js.map +1 -1
- package/lib/actions/preview.d.ts.map +1 -1
- package/lib/actions/preview.js +2 -2
- package/lib/actions/preview.js.map +1 -1
- package/lib/actions/upload.d.ts.map +1 -1
- package/lib/actions/upload.js.map +1 -1
- package/lib/cli.js +64 -0
- package/lib/cli.js.map +1 -1
- package/lib/convert/markdown-plugins/directive.d.ts +17 -0
- package/lib/convert/markdown-plugins/directive.d.ts.map +1 -0
- package/lib/convert/markdown-plugins/directive.js +30 -0
- package/lib/convert/markdown-plugins/directive.js.map +1 -0
- package/lib/convert/markdown-plugins/index.d.ts +51 -0
- package/lib/convert/markdown-plugins/index.d.ts.map +1 -0
- package/lib/convert/markdown-plugins/index.js +112 -0
- package/lib/convert/markdown-plugins/index.js.map +1 -0
- package/lib/convert/markdown-plugins/mermaid.d.ts +10 -0
- package/lib/convert/markdown-plugins/mermaid.d.ts.map +1 -0
- package/lib/convert/markdown-plugins/mermaid.js +103 -0
- package/lib/convert/markdown-plugins/mermaid.js.map +1 -0
- package/lib/convert/markdown-plugins/types.d.ts +43 -0
- package/lib/convert/markdown-plugins/types.d.ts.map +1 -0
- package/lib/convert/markdown-plugins/types.js +9 -0
- package/lib/convert/markdown-plugins/types.js.map +1 -0
- package/lib/convert/markdown-utils.d.ts +47 -0
- package/lib/convert/markdown-utils.d.ts.map +1 -0
- package/lib/convert/markdown-utils.js +136 -0
- package/lib/convert/markdown-utils.js.map +1 -0
- package/lib/convert/markdown.d.ts +15 -0
- package/lib/convert/markdown.d.ts.map +1 -0
- package/lib/convert/markdown.js +201 -0
- package/lib/convert/markdown.js.map +1 -0
- package/lib/convert/marp.d.ts +8 -1
- package/lib/convert/marp.d.ts.map +1 -1
- package/lib/convert/marp.js +35 -13
- package/lib/convert/marp.js.map +1 -1
- package/lib/convert/movie.d.ts.map +1 -1
- package/lib/convert/movie.js +10 -4
- package/lib/convert/movie.js.map +1 -1
- package/lib/convert/movie_bundle.d.ts.map +1 -1
- package/lib/convert/movie_bundle.js.map +1 -1
- package/lib/utils/audio-save.d.ts +7 -6
- package/lib/utils/audio-save.d.ts.map +1 -1
- package/lib/utils/audio-save.js +14 -24
- package/lib/utils/audio-save.js.map +1 -1
- package/package.json +13 -10
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Mermaid Plugin
|
|
4
|
+
*
|
|
5
|
+
* Converts ```mermaid code blocks to markdown with row-2 layout.
|
|
6
|
+
* This allows mermaid diagrams to be displayed alongside explanatory text.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.mermaidPlugin = void 0;
|
|
10
|
+
const MERMAID_REGEX = /```mermaid\n([\s\S]*?)```/g;
|
|
11
|
+
const MERMAID_SINGLE_REGEX = /```mermaid\n([\s\S]*?)```/;
|
|
12
|
+
/**
|
|
13
|
+
* Extract mermaid code blocks from markdown
|
|
14
|
+
*/
|
|
15
|
+
const extractMermaidBlocks = (markdown) => {
|
|
16
|
+
const matches = [...markdown.matchAll(MERMAID_REGEX)];
|
|
17
|
+
return matches.map((match) => match[1].trim());
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Extract non-mermaid content from markdown
|
|
21
|
+
*/
|
|
22
|
+
const extractNonMermaidContent = (markdown) => {
|
|
23
|
+
const content = markdown
|
|
24
|
+
.replace(MERMAID_REGEX, "")
|
|
25
|
+
.split("\n")
|
|
26
|
+
.map((line) => line.trimEnd())
|
|
27
|
+
.filter((line, index, arr) => {
|
|
28
|
+
// Remove leading empty lines
|
|
29
|
+
if (index === 0 && line === "")
|
|
30
|
+
return false;
|
|
31
|
+
// Remove trailing empty lines
|
|
32
|
+
if (index === arr.length - 1 && line === "")
|
|
33
|
+
return false;
|
|
34
|
+
return true;
|
|
35
|
+
});
|
|
36
|
+
// Remove consecutive empty lines (keep only one)
|
|
37
|
+
return content.reduce((acc, line) => {
|
|
38
|
+
if (line === "" && acc.length > 0 && acc[acc.length - 1] === "") {
|
|
39
|
+
return acc;
|
|
40
|
+
}
|
|
41
|
+
return [...acc, line];
|
|
42
|
+
}, []);
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Build mermaid code block as array of strings for markdown layout
|
|
46
|
+
*/
|
|
47
|
+
const buildMermaidLines = (mermaidCode) => [
|
|
48
|
+
"```mermaid",
|
|
49
|
+
...mermaidCode.split("\n"),
|
|
50
|
+
"```",
|
|
51
|
+
];
|
|
52
|
+
exports.mermaidPlugin = {
|
|
53
|
+
name: "mermaid",
|
|
54
|
+
priority: 10,
|
|
55
|
+
toBeat(markdown) {
|
|
56
|
+
const match = markdown.match(MERMAID_SINGLE_REGEX);
|
|
57
|
+
if (!match) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
const mermaidBlocks = extractMermaidBlocks(markdown);
|
|
61
|
+
const nonMermaidContent = extractNonMermaidContent(markdown);
|
|
62
|
+
// Single mermaid block with explanatory content -> row-2 layout
|
|
63
|
+
if (mermaidBlocks.length === 1 && nonMermaidContent.length > 0) {
|
|
64
|
+
const mermaidLines = buildMermaidLines(mermaidBlocks[0]);
|
|
65
|
+
return {
|
|
66
|
+
image: {
|
|
67
|
+
type: "markdown",
|
|
68
|
+
markdown: {
|
|
69
|
+
"row-2": [nonMermaidContent, mermaidLines],
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
// Multiple mermaid blocks -> 2x2 layout (alternating content and diagrams)
|
|
75
|
+
if (mermaidBlocks.length >= 2) {
|
|
76
|
+
const cells = mermaidBlocks.flatMap((code, index) => {
|
|
77
|
+
const label = [`### Diagram ${index + 1}`];
|
|
78
|
+
const mermaidLines = buildMermaidLines(code);
|
|
79
|
+
return [label, mermaidLines];
|
|
80
|
+
});
|
|
81
|
+
// If there's header content, use it
|
|
82
|
+
const headerContent = nonMermaidContent.length > 0 ? nonMermaidContent : undefined;
|
|
83
|
+
return {
|
|
84
|
+
image: {
|
|
85
|
+
type: "markdown",
|
|
86
|
+
markdown: headerContent
|
|
87
|
+
? { header: headerContent.join("\n"), "2x2": cells.slice(0, 4) }
|
|
88
|
+
: { "2x2": cells.slice(0, 4) },
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// Only mermaid (no explanatory content) -> simple markdown with mermaid code block
|
|
93
|
+
const mermaidLines = buildMermaidLines(mermaidBlocks[0]);
|
|
94
|
+
return {
|
|
95
|
+
image: {
|
|
96
|
+
type: "markdown",
|
|
97
|
+
markdown: mermaidLines,
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
exports.default = exports.mermaidPlugin;
|
|
103
|
+
//# sourceMappingURL=mermaid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaid.js","sourceRoot":"","sources":["../../../src/convert/markdown-plugins/mermaid.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown Plugin System Types
|
|
3
|
+
*
|
|
4
|
+
* Built-in plugins for markdown conversion.
|
|
5
|
+
* HTML rendering is done by mulmocast, not here.
|
|
6
|
+
*/
|
|
7
|
+
import type { MulmoBeat } from "mulmocast";
|
|
8
|
+
/**
|
|
9
|
+
* Separator modes for splitting markdown into slides
|
|
10
|
+
*/
|
|
11
|
+
export type SeparatorMode = "horizontal-rule" | "heading" | "heading-1" | "heading-2" | "heading-3" | "blank-lines" | "comment" | "page-break" | {
|
|
12
|
+
pattern: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Context passed to plugin processors (internal)
|
|
16
|
+
*/
|
|
17
|
+
export interface PluginContext {
|
|
18
|
+
slideIndex: number;
|
|
19
|
+
totalSlides: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Markdown Plugin Interface (internal)
|
|
23
|
+
*/
|
|
24
|
+
export interface MarkdownPlugin {
|
|
25
|
+
name: string;
|
|
26
|
+
priority?: number;
|
|
27
|
+
preprocess?: (markdown: string, context: PluginContext) => string;
|
|
28
|
+
toBeat?: (markdown: string, context: PluginContext) => Partial<MulmoBeat> | null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Markdown conversion options
|
|
32
|
+
*/
|
|
33
|
+
export interface MarkdownConvertOptions {
|
|
34
|
+
/** Separator mode for splitting slides */
|
|
35
|
+
separator?: SeparatorMode;
|
|
36
|
+
/** Enable mermaid plugin (converts mermaid code blocks to mermaid beat) */
|
|
37
|
+
mermaid?: boolean;
|
|
38
|
+
/** Enable directive plugin (removes Marp-style directives) */
|
|
39
|
+
directive?: boolean;
|
|
40
|
+
/** Style to apply to markdown slides */
|
|
41
|
+
style?: string;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/convert/markdown-plugins/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,iBAAiB,GACjB,SAAS,GACT,WAAW,GACX,WAAW,GACX,WAAW,GACX,aAAa,GACb,SAAS,GACT,YAAY,GACZ;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAExB;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,KAAK,MAAM,CAAC;IAClE,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;CAClF;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,0CAA0C;IAC1C,SAAS,CAAC,EAAE,aAAa,CAAC;IAE1B,2EAA2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/convert/markdown-plugins/types.ts"],"names":[],"mappings":";AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown Converter Utilities
|
|
3
|
+
*
|
|
4
|
+
* Types, constants, and helper functions for markdown conversion.
|
|
5
|
+
*/
|
|
6
|
+
import { type MulmoBeat } from "mulmocast";
|
|
7
|
+
import type { SupportedLang } from "../utils/lang";
|
|
8
|
+
import type { SeparatorMode } from "./markdown-plugins";
|
|
9
|
+
export interface Slide {
|
|
10
|
+
markdown: string;
|
|
11
|
+
beat: Partial<MulmoBeat> | null;
|
|
12
|
+
note: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ConvertMarkdownOptions {
|
|
15
|
+
inputPath: string;
|
|
16
|
+
outputDir?: string;
|
|
17
|
+
lang?: SupportedLang;
|
|
18
|
+
generateText?: boolean;
|
|
19
|
+
separator?: SeparatorMode;
|
|
20
|
+
mermaid?: boolean;
|
|
21
|
+
directive?: boolean;
|
|
22
|
+
style?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface ConvertMarkdownResult {
|
|
25
|
+
mulmoScriptPath: string;
|
|
26
|
+
slideCount: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Patterns to exclude from speaker notes
|
|
30
|
+
* Common code comments that should not be treated as narration
|
|
31
|
+
* Requires colon after keyword to avoid false positives (e.g., "Note 1" is OK)
|
|
32
|
+
*/
|
|
33
|
+
export declare const EXCLUDED_NOTE_PATTERNS: RegExp[];
|
|
34
|
+
export declare const SEPARATOR_CHOICES: readonly ["horizontal-rule", "heading", "heading-1", "heading-2", "heading-3", "blank-lines", "comment", "page-break"];
|
|
35
|
+
/**
|
|
36
|
+
* Extract speaker notes from HTML comments in a slide
|
|
37
|
+
* Excludes directive-like comments and common code comments (TODO, FIXME, etc.)
|
|
38
|
+
*/
|
|
39
|
+
export declare function extractNotesFromSlide(slideContent: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Extract markdown content from a slide (removes HTML comments)
|
|
42
|
+
*/
|
|
43
|
+
export declare function extractMarkdownFromSlide(slideContent: string): string[];
|
|
44
|
+
export declare function readMarkdownFile(inputPath: string): string;
|
|
45
|
+
export declare function setupOutputDirectory(basename: string, customOutputDir?: string): string;
|
|
46
|
+
export declare function writeMulmoScript(outputFolder: string, data: unknown): string;
|
|
47
|
+
//# sourceMappingURL=markdown-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-utils.d.ts","sourceRoot":"","sources":["../../src/convert/markdown-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMxD,MAAM,WAAW,KAAK;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,UAUlC,CAAC;AAEF,eAAO,MAAM,iBAAiB,wHASpB,CAAC;AASX;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAOlE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAMvE;AAMD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAY1D;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAQvF;AAED,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAW5E"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Markdown Converter Utilities
|
|
4
|
+
*
|
|
5
|
+
* Types, constants, and helper functions for markdown conversion.
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.SEPARATOR_CHOICES = exports.EXCLUDED_NOTE_PATTERNS = void 0;
|
|
42
|
+
exports.extractNotesFromSlide = extractNotesFromSlide;
|
|
43
|
+
exports.extractMarkdownFromSlide = extractMarkdownFromSlide;
|
|
44
|
+
exports.readMarkdownFile = readMarkdownFile;
|
|
45
|
+
exports.setupOutputDirectory = setupOutputDirectory;
|
|
46
|
+
exports.writeMulmoScript = writeMulmoScript;
|
|
47
|
+
const fs = __importStar(require("fs"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const mulmocast_1 = require("mulmocast");
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// Constants
|
|
52
|
+
// ============================================================================
|
|
53
|
+
/**
|
|
54
|
+
* Patterns to exclude from speaker notes
|
|
55
|
+
* Common code comments that should not be treated as narration
|
|
56
|
+
* Requires colon after keyword to avoid false positives (e.g., "Note 1" is OK)
|
|
57
|
+
*/
|
|
58
|
+
exports.EXCLUDED_NOTE_PATTERNS = [
|
|
59
|
+
/^TODO:/i,
|
|
60
|
+
/^FIXME:/i,
|
|
61
|
+
/^HACK:/i,
|
|
62
|
+
/^XXX:/i,
|
|
63
|
+
/^NOTE:/i,
|
|
64
|
+
/^BUG:/i,
|
|
65
|
+
/^WARN(ING)?:/i,
|
|
66
|
+
/^DEPRECATED:/i,
|
|
67
|
+
/^REVIEW:/i,
|
|
68
|
+
];
|
|
69
|
+
exports.SEPARATOR_CHOICES = [
|
|
70
|
+
"horizontal-rule",
|
|
71
|
+
"heading",
|
|
72
|
+
"heading-1",
|
|
73
|
+
"heading-2",
|
|
74
|
+
"heading-3",
|
|
75
|
+
"blank-lines",
|
|
76
|
+
"comment",
|
|
77
|
+
"page-break",
|
|
78
|
+
];
|
|
79
|
+
// ============================================================================
|
|
80
|
+
// Speaker Notes Extraction
|
|
81
|
+
// ============================================================================
|
|
82
|
+
const isExcludedComment = (comment) => exports.EXCLUDED_NOTE_PATTERNS.some((pattern) => pattern.test(comment));
|
|
83
|
+
/**
|
|
84
|
+
* Extract speaker notes from HTML comments in a slide
|
|
85
|
+
* Excludes directive-like comments and common code comments (TODO, FIXME, etc.)
|
|
86
|
+
*/
|
|
87
|
+
function extractNotesFromSlide(slideContent) {
|
|
88
|
+
const commentRegex = /<!--\s*([\s\S]*?)\s*-->/g;
|
|
89
|
+
return [...slideContent.matchAll(commentRegex)]
|
|
90
|
+
.map((m) => m[1].trim())
|
|
91
|
+
.filter((comment) => comment.length > 0)
|
|
92
|
+
.filter((comment) => !isExcludedComment(comment))
|
|
93
|
+
.join("\n");
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Extract markdown content from a slide (removes HTML comments)
|
|
97
|
+
*/
|
|
98
|
+
function extractMarkdownFromSlide(slideContent) {
|
|
99
|
+
const slideWithoutNotes = slideContent.replace(/<!--\s*[\s\S]*?\s*-->/g, "");
|
|
100
|
+
return slideWithoutNotes
|
|
101
|
+
.split("\n")
|
|
102
|
+
.map((line) => line.trim())
|
|
103
|
+
.filter((line) => line.length > 0);
|
|
104
|
+
}
|
|
105
|
+
// ============================================================================
|
|
106
|
+
// File I/O
|
|
107
|
+
// ============================================================================
|
|
108
|
+
function readMarkdownFile(inputPath) {
|
|
109
|
+
const resolvedPath = path.resolve(inputPath);
|
|
110
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
111
|
+
throw new Error(`File not found: ${resolvedPath}`);
|
|
112
|
+
}
|
|
113
|
+
if (!resolvedPath.endsWith(".md")) {
|
|
114
|
+
throw new Error("Input file must be a .md (Markdown) file");
|
|
115
|
+
}
|
|
116
|
+
return fs.readFileSync(resolvedPath, "utf-8");
|
|
117
|
+
}
|
|
118
|
+
function setupOutputDirectory(basename, customOutputDir) {
|
|
119
|
+
const outputFolder = customOutputDir || path.join(process.cwd(), "scripts", basename);
|
|
120
|
+
if (!fs.existsSync(outputFolder)) {
|
|
121
|
+
fs.mkdirSync(outputFolder, { recursive: true });
|
|
122
|
+
}
|
|
123
|
+
return outputFolder;
|
|
124
|
+
}
|
|
125
|
+
function writeMulmoScript(outputFolder, data) {
|
|
126
|
+
const result = mulmocast_1.mulmoScriptSchema.safeParse(data);
|
|
127
|
+
if (!result.success) {
|
|
128
|
+
console.error("MulmoScript validation failed:");
|
|
129
|
+
console.error(result.error.format());
|
|
130
|
+
throw new Error("Invalid MulmoScript generated");
|
|
131
|
+
}
|
|
132
|
+
const scriptPath = path.join(outputFolder, "mulmo_script.json");
|
|
133
|
+
fs.writeFileSync(scriptPath, JSON.stringify(result.data, null, 2), "utf-8");
|
|
134
|
+
return scriptPath;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=markdown-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-utils.js","sourceRoot":"","sources":["../../src/convert/markdown-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Markdown to MulmoScript converter
|
|
4
|
+
*
|
|
5
|
+
* Converts plain markdown files to MulmoScript format.
|
|
6
|
+
* Supports multiple separator modes and plugin system.
|
|
7
|
+
*/
|
|
8
|
+
import { type ConvertMarkdownOptions, type ConvertMarkdownResult, extractNotesFromSlide, extractMarkdownFromSlide } from "./markdown-utils";
|
|
9
|
+
export type { ConvertMarkdownOptions, ConvertMarkdownResult };
|
|
10
|
+
export { extractNotesFromSlide, extractMarkdownFromSlide };
|
|
11
|
+
/**
|
|
12
|
+
* Convert markdown file to MulmoScript
|
|
13
|
+
*/
|
|
14
|
+
export declare function convertMarkdown(options: ConvertMarkdownOptions): Promise<ConvertMarkdownResult>;
|
|
15
|
+
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/convert/markdown.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAQH,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAE1B,qBAAqB,EACrB,wBAAwB,EAIzB,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,CAAC;AA8B3D;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,qBAAqB,CAAC,CAwEhC"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Markdown to MulmoScript converter
|
|
5
|
+
*
|
|
6
|
+
* Converts plain markdown files to MulmoScript format.
|
|
7
|
+
* Supports multiple separator modes and plugin system.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
43
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
44
|
+
};
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.extractMarkdownFromSlide = exports.extractNotesFromSlide = void 0;
|
|
47
|
+
exports.convertMarkdown = convertMarkdown;
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const yargs_1 = __importDefault(require("yargs"));
|
|
50
|
+
const helpers_1 = require("yargs/helpers");
|
|
51
|
+
const lang_1 = require("../utils/lang");
|
|
52
|
+
const llm_1 = require("../utils/llm");
|
|
53
|
+
const markdown_plugins_1 = require("./markdown-plugins");
|
|
54
|
+
const markdown_utils_1 = require("./markdown-utils");
|
|
55
|
+
Object.defineProperty(exports, "extractNotesFromSlide", { enumerable: true, get: function () { return markdown_utils_1.extractNotesFromSlide; } });
|
|
56
|
+
Object.defineProperty(exports, "extractMarkdownFromSlide", { enumerable: true, get: function () { return markdown_utils_1.extractMarkdownFromSlide; } });
|
|
57
|
+
// ============================================================================
|
|
58
|
+
// Beat Generation
|
|
59
|
+
// ============================================================================
|
|
60
|
+
function slideToBeat(slide, style) {
|
|
61
|
+
// Use plugin-generated beat if available (e.g., mermaid with row-2 layout)
|
|
62
|
+
if (slide.beat?.image) {
|
|
63
|
+
return { text: slide.beat.text || slide.note, image: slide.beat.image };
|
|
64
|
+
}
|
|
65
|
+
// Default: markdown beat
|
|
66
|
+
const markdown = (0, markdown_utils_1.extractMarkdownFromSlide)(slide.markdown);
|
|
67
|
+
return {
|
|
68
|
+
text: slide.note,
|
|
69
|
+
image: style
|
|
70
|
+
? { type: "markdown", markdown, style }
|
|
71
|
+
: { type: "markdown", markdown },
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function slidesToMulmoScript(slides, lang, style) {
|
|
75
|
+
return {
|
|
76
|
+
$mulmocast: { version: "1.1", credit: "closing" },
|
|
77
|
+
lang,
|
|
78
|
+
beats: slides.map((slide) => slideToBeat(slide, style)),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Convert markdown file to MulmoScript
|
|
83
|
+
*/
|
|
84
|
+
async function convertMarkdown(options) {
|
|
85
|
+
const inputPath = path.resolve(options.inputPath);
|
|
86
|
+
const separator = options.separator ?? "horizontal-rule";
|
|
87
|
+
console.log("Starting Markdown to MulmoScript conversion...\n");
|
|
88
|
+
console.log(`Input file: ${inputPath}`);
|
|
89
|
+
console.log(`Separator: ${typeof separator === "string" ? separator : "custom pattern"}`);
|
|
90
|
+
// Setup
|
|
91
|
+
const basename = path.basename(inputPath, ".md");
|
|
92
|
+
const outputFolder = (0, markdown_utils_1.setupOutputDirectory)(basename, options.outputDir);
|
|
93
|
+
console.log(`Output directory: ${outputFolder}`);
|
|
94
|
+
// Read and split into slides
|
|
95
|
+
const content = (0, markdown_utils_1.readMarkdownFile)(inputPath);
|
|
96
|
+
const rawSlides = (0, markdown_plugins_1.splitIntoSlides)(content, separator);
|
|
97
|
+
console.log(`Found ${rawSlides.length} slides`);
|
|
98
|
+
// Log enabled plugins
|
|
99
|
+
const enabledPlugins = [options.mermaid && "mermaid", options.directive && "directive"].filter(Boolean);
|
|
100
|
+
if (enabledPlugins.length > 0) {
|
|
101
|
+
console.log(`Applying plugins: ${enabledPlugins.join(", ")}`);
|
|
102
|
+
}
|
|
103
|
+
// Process slides: apply plugins and extract notes
|
|
104
|
+
const slides = (0, markdown_plugins_1.processMarkdown)(rawSlides, {
|
|
105
|
+
mermaid: options.mermaid,
|
|
106
|
+
directive: options.directive,
|
|
107
|
+
}).map(({ markdown, beat }) => ({
|
|
108
|
+
markdown,
|
|
109
|
+
beat,
|
|
110
|
+
note: (0, markdown_utils_1.extractNotesFromSlide)(markdown),
|
|
111
|
+
}));
|
|
112
|
+
// Resolve language
|
|
113
|
+
const lang = (0, lang_1.resolveLang)(options.lang, slides.map((slide) => slide.note));
|
|
114
|
+
// Generate narration text with LLM if requested
|
|
115
|
+
if (options.generateText) {
|
|
116
|
+
console.log("Generating narration text with LLM...");
|
|
117
|
+
const slideData = slides.map((slide, index) => ({
|
|
118
|
+
index,
|
|
119
|
+
markdown: (0, markdown_utils_1.extractMarkdownFromSlide)(slide.markdown),
|
|
120
|
+
existingText: slide.note,
|
|
121
|
+
}));
|
|
122
|
+
const generatedTexts = await (0, llm_1.generateTextFromMarkdown)({
|
|
123
|
+
slides: slideData,
|
|
124
|
+
lang,
|
|
125
|
+
title: basename,
|
|
126
|
+
});
|
|
127
|
+
generatedTexts.forEach((generated) => {
|
|
128
|
+
slides[generated.index].note = generated.text;
|
|
129
|
+
});
|
|
130
|
+
console.log(`Generated text for ${generatedTexts.length} slides`);
|
|
131
|
+
}
|
|
132
|
+
// Generate and write MulmoScript
|
|
133
|
+
console.log("Generating MulmoScript JSON...");
|
|
134
|
+
const mulmoScript = slidesToMulmoScript(slides, lang, options.style);
|
|
135
|
+
const mulmoScriptPath = (0, markdown_utils_1.writeMulmoScript)(outputFolder, mulmoScript);
|
|
136
|
+
console.log(`✓ Created ${mulmoScriptPath}`);
|
|
137
|
+
console.log(`\n✓ Successfully converted ${slides.length} slides to MulmoScript`);
|
|
138
|
+
return { mulmoScriptPath, slideCount: slides.length };
|
|
139
|
+
}
|
|
140
|
+
// ============================================================================
|
|
141
|
+
// CLI
|
|
142
|
+
// ============================================================================
|
|
143
|
+
async function main() {
|
|
144
|
+
const argv = await (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
|
|
145
|
+
.usage("Usage: $0 <markdown-file.md> [options]")
|
|
146
|
+
.command("$0 <file>", "Convert Markdown to MulmoScript", (yargs) => {
|
|
147
|
+
return yargs.positional("file", {
|
|
148
|
+
describe: "Markdown file to convert",
|
|
149
|
+
type: "string",
|
|
150
|
+
demandOption: true,
|
|
151
|
+
});
|
|
152
|
+
})
|
|
153
|
+
.options({
|
|
154
|
+
...lang_1.langOption,
|
|
155
|
+
g: {
|
|
156
|
+
alias: "generate-text",
|
|
157
|
+
type: "boolean",
|
|
158
|
+
description: "Generate narration text using LLM",
|
|
159
|
+
default: false,
|
|
160
|
+
},
|
|
161
|
+
s: {
|
|
162
|
+
alias: "separator",
|
|
163
|
+
type: "string",
|
|
164
|
+
description: "Slide separator mode",
|
|
165
|
+
choices: markdown_utils_1.SEPARATOR_CHOICES,
|
|
166
|
+
default: "horizontal-rule",
|
|
167
|
+
},
|
|
168
|
+
mermaid: {
|
|
169
|
+
type: "boolean",
|
|
170
|
+
description: "Convert mermaid code blocks to mermaid beat type",
|
|
171
|
+
default: false,
|
|
172
|
+
},
|
|
173
|
+
directive: {
|
|
174
|
+
type: "boolean",
|
|
175
|
+
description: "Remove Marp-style directives (<!-- _class: ... -->)",
|
|
176
|
+
default: false,
|
|
177
|
+
},
|
|
178
|
+
style: {
|
|
179
|
+
type: "string",
|
|
180
|
+
description: "Markdown slide style (e.g., corporate-blue, finance-green)",
|
|
181
|
+
},
|
|
182
|
+
})
|
|
183
|
+
.help()
|
|
184
|
+
.parse();
|
|
185
|
+
await convertMarkdown({
|
|
186
|
+
inputPath: argv.file,
|
|
187
|
+
lang: argv.l,
|
|
188
|
+
generateText: argv.g,
|
|
189
|
+
separator: argv.s,
|
|
190
|
+
mermaid: argv.mermaid,
|
|
191
|
+
directive: argv.directive,
|
|
192
|
+
style: argv.style,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
if (require.main === module) {
|
|
196
|
+
main().catch((error) => {
|
|
197
|
+
console.error("\n✗ Error:", error instanceof Error ? error.message : String(error));
|
|
198
|
+
process.exit(1);
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/convert/markdown.ts"],"names":[],"mappings":"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"}
|
package/lib/convert/marp.d.ts
CHANGED
|
@@ -14,8 +14,15 @@ export interface ConvertMarpResult {
|
|
|
14
14
|
slideCount: number;
|
|
15
15
|
}
|
|
16
16
|
export declare function parseSlides(content: string): string[];
|
|
17
|
+
/**
|
|
18
|
+
* Extract speaker notes from HTML comments in a slide
|
|
19
|
+
* Excludes directive-like comments and common code comments (TODO, FIXME, etc.)
|
|
20
|
+
*/
|
|
17
21
|
export declare function extractNotesFromSlide(slideContent: string): string;
|
|
18
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Extract speaker notes from parsed slides
|
|
24
|
+
*/
|
|
25
|
+
export declare const extractNotesFromSlides: (slides: string[]) => string[];
|
|
19
26
|
export declare function extractMarkdownFromSlide(slideContent: string): string[];
|
|
20
27
|
export declare function extractMarkdownFromSlides(slides: string[]): string[][];
|
|
21
28
|
export declare function convertMarp(options: ConvertMarpOptions): Promise<ConvertMarpResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marp.d.ts","sourceRoot":"","sources":["../../src/convert/marp.ts"],"names":[],"mappings":";AAWA,OAAO,EAA2B,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAG5E,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAGD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAUrD;
|
|
1
|
+
{"version":3,"file":"marp.d.ts","sourceRoot":"","sources":["../../src/convert/marp.ts"],"names":[],"mappings":";AAWA,OAAO,EAA2B,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAG5E,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAGD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAUrD;AAyBD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAOlE;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,EAAE,KAAG,MAAM,EAC7B,CAAC;AAGpC,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAWvE;AAGD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,EAAE,CAQtE;AAyMD,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA8FzF"}
|