mlld
Version:
mlld: a modular prompt scripting language
171 lines (167 loc) • 5.88 kB
JavaScript
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