import type { ComicMetadata } from '@/types'; function escapeXml(str: string): string { return str .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } export function generateComicInfoXml(params: ComicMetadata): string { const lines: string[] = [ '', '', ]; if (params.title) { lines.push(` ${escapeXml(params.title)}`); } if (params.series) { lines.push(` ${escapeXml(params.series)}`); } if (params.number) { lines.push(` ${escapeXml(params.number)}`); } if (params.volume) { lines.push(` ${escapeXml(params.volume)}`); } if (params.writer) { lines.push(` ${escapeXml(params.writer)}`); } if (params.publisher) { lines.push(` ${escapeXml(params.publisher)}`); } if (params.genre) { lines.push(` ${escapeXml(params.genre)}`); } if (params.year) { const yearNum = parseInt(params.year, 10); if (!isNaN(yearNum)) { lines.push(` ${yearNum}`); } } if (params.communityRating) { const rating = parseFloat(params.communityRating); if (!isNaN(rating) && rating >= 0 && rating <= 5) { lines.push(` ${rating}`); } } lines.push(` ${params.pageCount}`); if (params.blackAndWhite) { lines.push(' Yes'); } if (params.manga) { lines.push(' YesAndRightToLeft'); } lines.push(''); return lines.join('\n'); } export function generateMetadataOpf(params: ComicMetadata): string { const lines: string[] = [ '', '', ' ', ]; if (params.title) { lines.push(` ${escapeXml(params.title)}`); } if (params.writer) { lines.push( ` ${escapeXml(params.writer)}` ); } if (params.publisher) { lines.push( ` ${escapeXml(params.publisher)}` ); } if (params.year) { const yearNum = parseInt(params.year, 10); if (!isNaN(yearNum)) { lines.push(` ${yearNum}-01-01`); } } if (params.genre) { lines.push(` ${escapeXml(params.genre)}`); } if (params.series) { lines.push( ` ` ); if (params.number) { lines.push( ` ` ); } } if (params.communityRating) { const rating = parseFloat(params.communityRating); if (!isNaN(rating) && rating >= 0 && rating <= 5) { lines.push( ` ` ); } } lines.push(' '); lines.push(''); return lines.join('\n'); } export function generateComicBookInfoJson(params: ComicMetadata): string { const info: Record = {}; if (params.title) { info.title = params.title; } if (params.series) { info.series = params.series; } if (params.number) { info.issue = params.number; } if (params.volume) { info.volume = parseInt(params.volume, 10) || undefined; } if (params.publisher) { info.publisher = params.publisher; } if (params.year) { const yearNum = parseInt(params.year, 10); if (!isNaN(yearNum)) { info.publicationYear = yearNum; } } if (params.genre) { info.tags = params.genre .split(',') .map((t) => t.trim()) .filter(Boolean); } if (params.writer) { info.credits = [{ person: params.writer, role: 'Writer' }]; } if (params.communityRating) { const rating = parseFloat(params.communityRating); if (!isNaN(rating) && rating >= 0 && rating <= 5) { info.rating = rating; } } const wrapper = { appID: 'BentoPDF/1.0', lastModified: new Date().toISOString(), 'ComicBookInfo/1.0': info, }; return JSON.stringify(wrapper); }