import { normalizeOptionalString } from "../shared/string-coerce.js" ;
const XML_ESCAPE_MAP: Record<string, string> = {
"<" : "<" ,
">" : ">" ,
"&" : "&" ,
'"' : """ ,
"'" : "'" ,
};
function xmlEscapeAttr(value: string): string {
return value.replace(/[<>&"']/g, (char) => XML_ESCAPE_MAP[char] ?? char);
}
function escapeFileBlockContent(value: string): string {
return value.replace(/<\s*\/\s*file\s*>/gi, "</file>" ).replace(/<\s*file\b/gi, "<file" );
}
function sanitizeFileName(value: string | null | undefined, fallbackName: string): string {
const normalized =
normalizeOptionalString(
typeof value === "string" ? value.replace(/[\r\n\t]+/g, " " ) : undefined,
) ?? "" ;
return normalized || fallbackName;
}
export function renderFileContextBlock(params: {
filename?: string | null ;
fallbackName?: string;
mimeType?: string | null ;
content: string;
surroundContentWithNewlines?: boolean ;
}): string {
const fallbackName = normalizeOptionalString(params.fallbackName) ?? "attachment" ;
const safeName = sanitizeFileName(params.filename, fallbackName);
const safeContent = escapeFileBlockContent(params.content);
const mimeType = normalizeOptionalString(params.mimeType);
const attrs = [
`name="${xmlEscapeAttr(safeName)}" `,
mimeType ? `mime="${xmlEscapeAttr(mimeType)}" ` : undefined,
]
.filter(Boolean )
.join(" " );
if (params.surroundContentWithNewlines === false ) {
return `<file ${attrs}>${safeContent}</file>`;
}
return `<file ${attrs}>\n${safeContent}\n</file>`;
}
Messung V0.5 in Prozent C=98 H=96 G=96
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland