UNPKG

mlld

Version:

mlld: a modular prompt scripting language

171 lines (167 loc) 5.88 kB
import { llmxmlInstance } from './chunk-GPFWQ7PB.mjs'; import { isTextLike, isObject, isArray, isPath, isExecutable, isImported } from './chunk-V5L6FBQT.mjs'; import { __name } from './chunk-OMKLS24H.mjs'; import * as prettier from 'prettier'; var hasWarnedAboutHanging = false; async function formatMarkdown(content) { try { const TRAILING_SPACE_MARKER = "\u27EAMLLD_TRAILING_SPACE\u27EB"; const JSON_BLOCK_MARKER = "\u27EAMLLD_JSON_BLOCK_"; const JSON_BLOCK_END = "\u27EB"; const jsonBlocks = []; let protectedContent = content; const multilineJsonRegex = /(\{[^{}]*(?:\{[^{}]*\}[^{}]*)*\})/g; protectedContent = protectedContent.replace(multilineJsonRegex, (match) => { if (match.includes("\n ")) { const index = jsonBlocks.length; jsonBlocks.push(match); return `${JSON_BLOCK_MARKER}${index}${JSON_BLOCK_END}`; } return match; }); const lines = protectedContent.split("\n"); const trailingSpaceInfo = lines.map((line) => { const match = line.match(/(\s+)$/); return match ? match[1].length : 0; }); const markedContent = lines.map((line) => { return line.replace(/\s+$/, TRAILING_SPACE_MARKER); }).join("\n"); const formatted = await prettier.format(markedContent, { parser: "markdown", // Preserve existing line breaks where possible proseWrap: "preserve", // Use 80 character line length for wrapping printWidth: 80, // Ensure consistent spacing tabWidth: 2, useTabs: false, // Don't add trailing commas in markdown code blocks trailingComma: "none", // Single quotes in code blocks singleQuote: true, // Preserve empty lines endOfLine: "lf", // Try to preserve formatting in certain contexts embeddedLanguageFormatting: "auto" }); let restoredContent = formatted; jsonBlocks.forEach((block, index) => { const marker = `${JSON_BLOCK_MARKER}${index}${JSON_BLOCK_END}`; restoredContent = restoredContent.replace(marker, block); }); const formattedLines = restoredContent.split("\n"); const restoredLines = formattedLines.map((line, index) => { if (line.includes(TRAILING_SPACE_MARKER)) { const originalIndex = Math.min(index, trailingSpaceInfo.length - 1); const spaceCount = trailingSpaceInfo[originalIndex] || 0; if (spaceCount > 0) { return line.replace(new RegExp(TRAILING_SPACE_MARKER, "g"), " ".repeat(spaceCount)); } } return line.replace(new RegExp(TRAILING_SPACE_MARKER, "g"), ""); }); if (!hasWarnedAboutHanging && process.env.MLLD_CLI_MODE === "true") { hasWarnedAboutHanging = true; } return restoredLines.join("\n"); } catch (error) { console.warn("Prettier formatting failed:", error); return content; } } __name(formatMarkdown, "formatMarkdown"); // interpreter/utils/blank-line-normalizer.ts function normalizeOutputBlankLines(content) { return content.replace(/\n{3,}/g, "\n\n"); } __name(normalizeOutputBlankLines, "normalizeOutputBlankLines"); // interpreter/output/formatter.ts async function formatOutput(nodes, options) { if (options.format === "xml") { const structuredMarkdown = await buildStructuredMarkdown(nodes, options); return await llmxmlInstance.toXML(structuredMarkdown); } return formatMarkdownNodes(nodes, options); } __name(formatOutput, "formatOutput"); async function formatMarkdownNodes(nodes, options) { const parts = []; for (const node of nodes) { switch (node.type) { case "Text": parts.push(node.content); break; case "Newline": parts.push("\n"); break; case "CodeFence": const fence = "```"; const lang = node.language || ""; const content = node.content || ""; parts.push(`${fence}${lang} ${content} ${fence}`); break; } } let result = parts.join(""); const useFormatter = options.useMarkdownFormatter !== false; if (useFormatter) { result = await formatMarkdown(result); } else { const shouldNormalize = options.normalizeBlankLines !== false; if (shouldNormalize) { result = result.trim(); result = normalizeOutputBlankLines(result); if (result.length > 0) { result += "\n"; } } } return result; } __name(formatMarkdownNodes, "formatMarkdownNodes"); async function buildStructuredMarkdown(nodes, options) { const parts = []; parts.push("# Mlld Output"); parts.push(""); if (options.variables && options.variables.size > 0) { parts.push("## Variables"); parts.push(""); for (const [name, variable] of options.variables) { const value = getVariableValue(variable); parts.push(`### ${name}`); parts.push(`- **Type**: ${variable.type}`); parts.push(`- **Value**: ${value}`); parts.push(""); } } const content = await formatMarkdownNodes(nodes, options); if (content.trim()) { parts.push("## Content"); parts.push(""); parts.push(content); } return parts.join("\n"); } __name(buildStructuredMarkdown, "buildStructuredMarkdown"); function getVariableValue(variable) { if (isTextLike(variable)) { return variable.value; } else if (isObject(variable) || isArray(variable)) { return JSON.stringify(variable.value, null, 2); } else if (isPath(variable)) { return variable.value; } else if (isExecutable(variable)) { return JSON.stringify(variable.definition); } else if (isImported(variable)) { return `Imported from ${variable.source}`; } else { throw new Error(`Unknown variable type in formatter: ${variable.type}`); } } __name(getVariableValue, "getVariableValue"); export { formatMarkdown, formatOutput }; //# sourceMappingURL=chunk-S3VE3NJA.mjs.map //# sourceMappingURL=chunk-S3VE3NJA.mjs.map