Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 56 additions & 3 deletions src/components/EcosystemItem/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import type { ReactNode } from 'react';
import Layout from '@theme/Layout';
import Admonition from '@theme/Admonition';
import Link from '@docusaurus/Link';
import { useLocation } from '@docusaurus/router';
import ReactMarkdown from 'react-markdown';
Expand Down Expand Up @@ -354,8 +355,57 @@ function resolveUrl(src: string, rawBaseUrl: string): string {
}
}

// GitHub alert markers (> [!WARNING]) mapped to Docusaurus admonition types, so a
// README renders the same callouts here as it does on GitHub.
const GITHUB_ALERT_TYPES: Record<string, string> = {
NOTE: 'note',
TIP: 'tip',
IMPORTANT: 'info',
WARNING: 'warning',
CAUTION: 'danger',
};

// remark-gfm does not implement GitHub alerts, so they arrive as plain blockquotes
// with a literal "[!WARNING]" prefix. This rewrites those into an `admonition` node
// that createMdComponents renders with the theme's own Admonition component.
function remarkGithubAlerts() {
return (tree: any) => {
const walk = (node: any) => {
if (node.type === 'blockquote') {
const paragraph = node.children?.[0];
const text = paragraph?.type === 'paragraph' ? paragraph.children?.[0] : undefined;
const match =
text?.type === 'text'
? /^\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\][ \t]*\r?\n?/.exec(text.value)
: null;
if (match) {
text.value = text.value.slice(match[0].length);
if (!text.value) {
// The marker sat on its own; drop it, and the paragraph too if that
// emptied it, which is the case for the multi-paragraph alert form.
paragraph.children.shift();
if (paragraph.children.length === 0) {
node.children.shift();
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
node.data = {
...node.data,
hName: 'admonition',
hProperties: { type: GITHUB_ALERT_TYPES[match[1]] },
};
}
}
node.children?.forEach(walk);
};
walk(tree);
};
}

function createMdComponents(rawBaseUrl: string) {
return {
admonition({ type, children }: { type?: string; children?: ReactNode }) {
return <Admonition type={type ?? 'note'}>{children}</Admonition>;
},
pre({ children }: { children?: ReactNode }) {
return <>{children}</>;
},
Expand Down Expand Up @@ -751,7 +801,7 @@ export default function EcosystemItem(): ReactNode {
))
) : (
<ReactMarkdown
remarkPlugins={[remarkGfm]}
remarkPlugins={[remarkGfm, remarkGithubAlerts]}
components={marketplaceMdComponents as any}
>
{section.body}
Expand Down Expand Up @@ -790,7 +840,10 @@ export default function EcosystemItem(): ReactNode {
{parsed.intro && (
<div className={styles.introCard}>
<div className={styles.markdownContent}>
<ReactMarkdown remarkPlugins={[remarkGfm]} components={mdComponents as any}>
<ReactMarkdown
remarkPlugins={[remarkGfm, remarkGithubAlerts]}
components={mdComponents as any}
>
{parsed.intro}
</ReactMarkdown>
</div>
Expand Down Expand Up @@ -898,7 +951,7 @@ export default function EcosystemItem(): ReactNode {
)}
<div className={styles.markdownContent}>
<ReactMarkdown
remarkPlugins={[remarkGfm]}
remarkPlugins={[remarkGfm, remarkGithubAlerts]}
components={mdComponents as any}
>
{activeSection.content}
Expand Down