const fs = require("fs-extra"); function escapeXml(str) { if (typeof str !== "string") { return String(str); } return str .replace(/&/g, "&") .replace(/ ` ${line}`); } function generateXMLOutput(aggregatedContent, outputPath) { const { textFiles } = aggregatedContent; const writeStream = fs.createWriteStream(outputPath, { encoding: "utf8" }); return new Promise((resolve, reject) => { writeStream.on("error", reject); writeStream.on("finish", resolve); writeStream.write('\n'); writeStream.write("\n"); // Sort files by path for deterministic order const filesSorted = [...textFiles].sort((a, b) => a.path.localeCompare(b.path) ); let index = 0; const writeNext = () => { if (index >= filesSorted.length) { writeStream.write("\n"); writeStream.end(); return; } const file = filesSorted[index++]; const p = escapeXml(file.path); const content = typeof file.content === "string" ? file.content : ""; if (content.length === 0) { writeStream.write(`\t\n`); setTimeout(writeNext, 0); return; } const needsCdata = content.includes("<") || content.includes("&") || content.includes("]]>"); if (needsCdata) { // Open tag and CDATA on their own line with tab indent; content lines indented with two tabs writeStream.write(`\t" inside content, trim trailing newlines, indent each line with two tabs const safe = content.replace(/]]>/g, "]]]]>"); const trimmed = safe.replace(/[\r\n]+$/, ""); const indented = trimmed.length > 0 ? trimmed.split("\n").map((line) => `\t\t${line}`).join("\n") : ""; writeStream.write(indented); // Close CDATA and attach closing tag directly after the last content line writeStream.write("]]>\n"); } else { // Write opening tag then newline; indent content with two tabs; attach closing tag directly after last content char writeStream.write(`\t\n`); const trimmed = content.replace(/[\r\n]+$/, ""); const indented = trimmed.length > 0 ? trimmed.split("\n").map((line) => `\t\t${line}`).join("\n") : ""; writeStream.write(indented); writeStream.write(`\n`); } setTimeout(writeNext, 0); }; writeNext(); }); } module.exports = { generateXMLOutput };