@markdown-ui/marked-ext
Advanced tools
+19
-0
| import { type MarkedExtension } from 'marked'; | ||
| export interface MarkedUiExtensionOptions { | ||
| /** | ||
| * Enable streaming mode for AI content generation. | ||
| * When true, uses streaming-aware parser that handles incomplete input gracefully. | ||
| */ | ||
| streaming?: boolean; | ||
| } | ||
| /** | ||
| * Create a marked extension for markdown-ui widgets. | ||
| * @param options Configuration options | ||
| */ | ||
| export declare function createMarkedUiExtension(options?: MarkedUiExtensionOptions): MarkedExtension; | ||
| /** | ||
| * Default marked extension (non-streaming mode for backward compatibility) | ||
| */ | ||
| export declare const markedUiExtension: MarkedExtension; | ||
| /** | ||
| * Streaming-aware marked extension for AI content generation | ||
| */ | ||
| export declare const markedUiStreamingExtension: MarkedExtension; |
+64
-32
| import { nanoid } from 'nanoid'; | ||
| import { parseDSL } from '@markdown-ui/mdui-lang'; | ||
| export const markedUiExtension = { | ||
| renderer: { | ||
| code(token) { | ||
| const lang = token.lang; | ||
| if (lang === "markdown-ui-widget") { | ||
| const text = token.text.trim(); | ||
| let payloadJson = {}; | ||
| let finalPayload; | ||
| // Try JSON first | ||
| try { | ||
| payloadJson = JSON.parse(text); | ||
| finalPayload = text; // Use original JSON | ||
| } | ||
| catch (e) { | ||
| // Not JSON, try DSL | ||
| const result = parseDSL(text); | ||
| if (result.success && result.widget) { | ||
| payloadJson = result.widget; | ||
| finalPayload = JSON.stringify(result.widget); | ||
| import { parseDSL, parseDSLStreaming } from '@markdown-ui/mdui-lang'; | ||
| /** | ||
| * Create a marked extension for markdown-ui widgets. | ||
| * @param options Configuration options | ||
| */ | ||
| export function createMarkedUiExtension(options = {}) { | ||
| const { streaming = false } = options; | ||
| return { | ||
| renderer: { | ||
| code(token) { | ||
| const lang = token.lang; | ||
| if (lang === "markdown-ui-widget") { | ||
| const text = token.text.trim(); | ||
| let payloadJson = {}; | ||
| let finalPayload; | ||
| // Try JSON first | ||
| try { | ||
| payloadJson = JSON.parse(text); | ||
| finalPayload = text; // Use original JSON | ||
| } | ||
| else { | ||
| // Failed to parse both, render as code block | ||
| return false; | ||
| catch (e) { | ||
| // Not JSON, try DSL parsing | ||
| if (streaming) { | ||
| // Use streaming-aware parser for AI content | ||
| const result = parseDSLStreaming(text); | ||
| if (result.widget) { | ||
| payloadJson = result.widget; | ||
| // Add streaming metadata | ||
| payloadJson._streaming = !result.complete; | ||
| payloadJson._pending = result.pending; | ||
| finalPayload = JSON.stringify(payloadJson); | ||
| } | ||
| else { | ||
| // Can't even detect widget type, render as code block | ||
| return false; | ||
| } | ||
| } | ||
| else { | ||
| // Use standard parser | ||
| const result = parseDSL(text); | ||
| if (result.success && result.widget) { | ||
| payloadJson = result.widget; | ||
| finalPayload = JSON.stringify(result.widget); | ||
| } | ||
| else { | ||
| // Failed to parse, render as code block | ||
| return false; | ||
| } | ||
| } | ||
| } | ||
| const payload = encodeURIComponent(finalPayload); | ||
| const id = payloadJson.id || nanoid(); | ||
| return `<markdown-ui-widget id="${id}" content="${payload}"></markdown-ui-widget>\n`; | ||
| } | ||
| // console.log(finalPayload); | ||
| const payload = encodeURIComponent(finalPayload); | ||
| const id = payloadJson.id || nanoid(); | ||
| return `<markdown-ui-widget id="${id}" content="${payload}"></markdown-ui-widget>\n`; | ||
| } | ||
| // fall back to default rendering | ||
| return false; // tells marked to use its default renderer for other languages | ||
| // fall back to default rendering | ||
| return false; // tells marked to use its default renderer for other languages | ||
| }, | ||
| }, | ||
| }, | ||
| }; | ||
| }; | ||
| } | ||
| /** | ||
| * Default marked extension (non-streaming mode for backward compatibility) | ||
| */ | ||
| export const markedUiExtension = createMarkedUiExtension({ streaming: false }); | ||
| /** | ||
| * Streaming-aware marked extension for AI content generation | ||
| */ | ||
| export const markedUiStreamingExtension = createMarkedUiExtension({ streaming: true }); |
+2
-2
| { | ||
| "version": "1.3.1", | ||
| "version": "1.4.0", | ||
| "description": "Marked extension for markdown-ui widgets", | ||
@@ -28,3 +28,3 @@ "name": "@markdown-ui/marked-ext", | ||
| "nanoid": "^5.1.5", | ||
| "@markdown-ui/mdui-lang": "0.3.3" | ||
| "@markdown-ui/mdui-lang": "0.4.0" | ||
| }, | ||
@@ -31,0 +31,0 @@ "devDependencies": { |
7388
43.4%90
130.77%+ Added
- Removed
Updated