diff --git a/src/lib/glossary.ts b/src/lib/glossary.ts index 8d969ea..1280217 100644 --- a/src/lib/glossary.ts +++ b/src/lib/glossary.ts @@ -128,17 +128,35 @@ export function uniqueGlossaryEntries( return out; } -export function resolveGlossaryEntries( +export function resolveGlossaryEntriesInSourceOrder( slugs: string[] = [], allEntries: GlossaryEntry[] = [], ): GlossaryEntry[] { const bySlug = buildGlossaryBySlug(allEntries); + const seen = new Set(); + const resolved: GlossaryEntry[] = []; - const resolved = slugs - .map((slug) => bySlug.get(normalizeGlossarySlug(slug))) - .filter(Boolean) as GlossaryEntry[]; + for (const rawSlug of slugs) { + const slug = normalizeGlossarySlug(rawSlug); + if (!slug || seen.has(slug)) continue; - return sortGlossaryEntries(uniqueGlossaryEntries(resolved)); + const entry = bySlug.get(slug); + if (!entry) continue; + + seen.add(slug); + resolved.push(entry); + } + + return resolved; +} + +export function resolveGlossaryEntries( + slugs: string[] = [], + allEntries: GlossaryEntry[] = [], + ): GlossaryEntry[] { + return sortGlossaryEntries( + resolveGlossaryEntriesInSourceOrder(slugs, allEntries), + ); } export function rawFamilyOf( @@ -268,31 +286,44 @@ export type GlossaryRelationBlock = { }; export function getRelationBlocks( - entry: GlossaryEntry, - allEntries: GlossaryEntry[] = [], -): GlossaryRelationBlock[] { - const relatedEntries = resolveGlossaryEntries(entry.data.related ?? [], allEntries); - const opposedEntries = resolveGlossaryEntries(entry.data.opposedTo ?? [], allEntries); - const seeAlsoEntries = resolveGlossaryEntries(entry.data.seeAlso ?? [], allEntries); - - return [ - { - title: "Concepts liés", - items: relatedEntries, - className: "is-related", - }, - { - title: "En tension avec", - items: opposedEntries, - className: "is-opposed", - }, - { - title: "Voir aussi", - items: seeAlsoEntries, - className: "is-see-also", - }, - ].filter((block) => block.items.length > 0); -} + entry: GlossaryEntry, + allEntries: GlossaryEntry[] = [], + ): GlossaryRelationBlock[] { + const currentSlug = slugOfGlossaryEntry(entry); + + const relatedEntries = resolveGlossaryEntriesInSourceOrder( + entry.data.related ?? [], + allEntries, + ).filter((item) => slugOfGlossaryEntry(item) !== currentSlug); + + const opposedEntries = resolveGlossaryEntriesInSourceOrder( + entry.data.opposedTo ?? [], + allEntries, + ).filter((item) => slugOfGlossaryEntry(item) !== currentSlug); + + const seeAlsoEntries = resolveGlossaryEntriesInSourceOrder( + entry.data.seeAlso ?? [], + allEntries, + ).filter((item) => slugOfGlossaryEntry(item) !== currentSlug); + + return [ + { + title: "Concepts liés", + items: relatedEntries, + className: "is-related", + }, + { + title: "En tension avec", + items: opposedEntries, + className: "is-opposed", + }, + { + title: "Voir aussi", + items: seeAlsoEntries, + className: "is-see-also", + }, + ].filter((block) => block.items.length > 0); + } export function getRelationSections( entry: GlossaryEntry,