UNPKG

@meldscience/meld

Version:

pipeable one-shot prompt scripting toolkit

97 lines (85 loc) 2.93 kB
import { Node } from 'unist'; import { buildMeldDirectiveNode } from './parseMeldDirective'; import { Handle } from 'mdast-util-to-markdown'; import { Text, Parent, RootContent, RootContentMap } from 'mdast'; import { visit } from 'unist-util-visit'; import { Plugin } from 'unified'; declare module 'mdast' { interface RootContentMap { meldDirective: MeldDirectiveNode; } } export interface MeldDirectiveNode extends Node { type: 'meldDirective'; meldType: 'cmd' | 'import'; raw: string; lineNumber?: number; data?: { command?: string; importPath?: string; heading?: string; importSymbol?: string; importSymbolList?: string[]; headingLevelOverride?: string; headingTextOverride?: string; importWholeFile?: boolean; }; } export const remarkMeldDirectives: Plugin = function remarkMeldDirectives() { return (tree: Node, file: any) => { // Store the AST in file.data for testing file.data.ast = tree; visit(tree, 'text', (node: Text, index: number | null, parent: Parent) => { if (!node.value || !parent || index === null) return; const newNodes: RootContent[] = []; let lastIndex = 0; const regex = /@(cmd|import)(?:\[([^\[\]]*(?:\[[^\[\]]*\][^\[\]]*)*)\])?(?:\s+as\s+#{1,6}(?:\s+"[^"]*")?)?/g; let match: RegExpExecArray | null; console.log('Node value:', node.value); while ((match = regex.exec(node.value)) !== null) { const [fullMatch, type, content] = match; const start = match.index; console.log('Full match:', fullMatch); console.log('Type:', type); console.log('Content:', content); // Add text before the match if (start > lastIndex) { newNodes.push({ type: 'text', value: node.value.slice(lastIndex, start) } as Text); } try { if (!content || !fullMatch.includes('[') || !fullMatch.includes(']')) { throw new Error(type === 'cmd' ? 'Invalid command format' : 'Invalid import format'); } const meldNode = buildMeldDirectiveNode(fullMatch); newNodes.push(meldNode); } catch (err: any) { // If parsing fails, keep the original text newNodes.push({ type: 'text', value: fullMatch } as Text); newNodes.push({ type: 'text', value: ` Error: ${err.message}` } as Text); } lastIndex = start + fullMatch.length; } // Add remaining text if (lastIndex < node.value.length) { newNodes.push({ type: 'text', value: node.value.slice(lastIndex) } as Text); } if (newNodes.length > 0) { // Replace the current node with our new nodes parent.children.splice(index, 1, ...newNodes); return index + newNodes.length; } }); }; }