--- import HtmlEmbed from "./HtmlEmbed.astro"; interface Props { title: string; // may contain HTML (e.g.,
) titleRaw?: string; // plain title for slug/PDF (optional) description?: string; authors?: Array; affiliations?: Array<{ id: number; name: string; url?: string }>; affiliation?: string; // legacy single affiliation published?: string; doi?: string; } const { title, titleRaw, description, authors = [], affiliations = [], affiliation, published, doi } = Astro.props as Props; type Author = { name: string; url?: string; affiliationIndices?: number[] }; function normalizeAuthors(input: Array): Author[] { return (Array.isArray(input) ? input : []) .map((a) => { if (typeof a === 'string') { return { name: a } as Author; } const name = (a?.name ?? '').toString(); const url = (a?.url ?? a?.link) as string | undefined; const affiliationIndices = Array.isArray((a as any)?.affiliationIndices) ? (a as any).affiliationIndices : undefined; return { name, url, affiliationIndices } as Author; }) .filter((a) => a.name && a.name.trim().length > 0); } const normalizedAuthors: Author[] = normalizeAuthors(authors as any); // Determine if affiliation superscripts should be shown (only when there are multiple distinct affiliations referenced by authors) const authorAffiliationIndexSet = new Set(); for (const author of normalizedAuthors) { const indices = Array.isArray(author.affiliationIndices) ? author.affiliationIndices : []; for (const idx of indices) { if (typeof idx === 'number') { authorAffiliationIndexSet.add(idx); } } } const shouldShowAffiliationSupers = authorAffiliationIndexSet.size > 1; const hasMultipleAffiliations = Array.isArray(affiliations) && affiliations.length > 1; function stripHtml(text: string): string { return String(text || '').replace(/<[^>]*>/g, ''); } function slugify(text: string): string { return String(text || '') .normalize('NFKD') .replace(/\p{Diacritic}+/gu, '') .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/^-+|-+$/g, '') .slice(0, 120) || 'article'; } const pdfBase = titleRaw ? stripHtml(titleRaw) : stripHtml(title); const pdfFilename = `${slugify(pdfBase)}.pdf`; ---

{description &&

{description}

}
{normalizedAuthors.length > 0 && (

Author{normalizedAuthors.length > 1 ? 's' : ''}

    {normalizedAuthors.map((a, i) => { const supers = shouldShowAffiliationSupers && Array.isArray(a.affiliationIndices) && a.affiliationIndices.length ? {a.affiliationIndices.join(',')} : null; return (
  • {a.url ? {a.name} : a.name}{supers}
  • ); })}
)} {(Array.isArray(affiliations) && affiliations.length > 0) && (

Affiliation{affiliations.length > 1 ? 's' : ''}

{hasMultipleAffiliations ? (
    {affiliations.map((af) => (
  1. {af.url ? {af.name} : af.name}
  2. ))}
) : (

{affiliations[0]?.url ? {affiliations[0].name} : affiliations[0]?.name}

)}
)} {(!affiliations || affiliations.length === 0) && affiliation && (

Affiliation

{affiliation}

)} {published && (

Published

{published}

)}