diff --git a/src/lib/discussion-topics.ts b/src/lib/discussion-topics.ts index 6c7d400..f97b64f 100644 --- a/src/lib/discussion-topics.ts +++ b/src/lib/discussion-topics.ts @@ -3,14 +3,47 @@ import { NostrEvent } from 'nostr-tools' /** * Normalize a topic string to lowercase with hyphens, no spaces + * Also converts plurals to singular form */ export function normalizeTopic(topic: string): string { - return topic + let normalized = topic .toLowerCase() .replace(/\s+/g, '-') .replace(/[^a-z0-9-]/g, '') .replace(/-+/g, '-') .replace(/^-|-$/g, '') + + // Convert plural to singular (simple English plurals) + // Handle common cases: -ies -> -y, -es -> (sometimes), -s -> remove + if (normalized.endsWith('ies') && normalized.length > 4) { + // cities -> city, berries -> berry + normalized = normalized.slice(0, -3) + 'y' + } else if (normalized.endsWith('ves') && normalized.length > 4) { + // wives -> wife, knives -> knife + normalized = normalized.slice(0, -3) + 'fe' + } else if (normalized.endsWith('ses') && normalized.length > 4) { + // classes -> class, bosses -> boss + normalized = normalized.slice(0, -2) + } else if (normalized.endsWith('xes') && normalized.length > 4) { + // boxes -> box + normalized = normalized.slice(0, -2) + } else if (normalized.endsWith('shes') && normalized.length > 5) { + // dishes -> dish + normalized = normalized.slice(0, -2) + } else if (normalized.endsWith('ches') && normalized.length > 5) { + // churches -> church + normalized = normalized.slice(0, -2) + } else if (normalized.endsWith('s') && normalized.length > 2) { + // Simple plural: cats -> cat, bitcoins -> bitcoin + // But avoid removing 's' from words that naturally end in 's' + // Check if second-to-last character is not 's' to avoid "ss" words + const secondLast = normalized[normalized.length - 2] + if (secondLast !== 's') { + normalized = normalized.slice(0, -1) + } + } + + return normalized } /** @@ -91,9 +124,10 @@ export function analyzeThreadTopics( const analysis = topicMap.get(primaryTopic)! analysis.threads.push(thread) - // Track subtopics (all topics except the primary one and 'general'/'all') + // Track subtopics (all topics except the primary one and 'all'/'all-topics') + // For 'general' topic, include all other topics as subtopics const subtopics = allTopics.filter( - t => t !== primaryTopic && t !== 'general' && t !== 'all' && t !== 'all-topics' + t => t !== primaryTopic && t !== 'all' && t !== 'all-topics' ) for (const subtopic of subtopics) {