);
};
// Helper function to process citations within React children
const processCitationsInReactChildren = (children: React.ReactNode, getCitationSource: (id: number) => Source | null): React.ReactNode => {
// If children is not an array or string, just return it
if (!children || (typeof children !== 'string' && !Array.isArray(children))) {
return children;
}
// Handle string content directly - this is where we process citation references
if (typeof children === 'string') {
return processCitationsInText(children, getCitationSource);
}
// Handle arrays of children recursively
if (Array.isArray(children)) {
return React.Children.map(children, child => {
if (typeof child === 'string') {
return processCitationsInText(child, getCitationSource);
}
return child;
});
}
return children;
};
// Process citation references in text content
const processCitationsInText = (text: string, getCitationSource: (id: number) => Source | null): React.ReactNode[] => {
// Use improved regex to catch citation numbers more reliably
// This will match patterns like [1], [42], etc. including when they appear at the end of a line or sentence
const citationRegex = /\[(\d+)\]/g;
const parts: React.ReactNode[] = [];
let lastIndex = 0;
let match;
let position = 0;
while ((match = citationRegex.exec(text)) !== null) {
// Add text before the citation
if (match.index > lastIndex) {
parts.push(text.substring(lastIndex, match.index));
}
// Add the citation component
const citationId = parseInt(match[1], 10);
const source = getCitationSource(citationId);
parts.push(
);
lastIndex = match.index + match[0].length;
position++;
}
// Add any remaining text after the last citation
if (lastIndex < text.length) {
parts.push(text.substring(lastIndex));
}
return parts;
};