import type { Code, InlineCode } from 'myst-spec'; import type { NodeRenderer } from './types'; import { useTheme } from '@curvenote/ui-providers'; import { LightAsync as SyntaxHighlighter } from 'react-syntax-highlighter'; import light from 'react-syntax-highlighter/dist/cjs/styles/hljs/xcode'; import dark from 'react-syntax-highlighter/dist/cjs/styles/hljs/vs2015'; import classNames from 'classnames'; import { CopyIcon } from './components/CopyIcon'; type Props = { value: string; lang?: string; showCopy?: boolean; showLineNumbers?: boolean; emphasizeLines?: number[]; className?: string; }; export function CodeBlock(props: Props) { const { isLight } = useTheme(); const { value, lang, emphasizeLines, showLineNumbers, className, showCopy = true } = props; const highlightLines = new Set(emphasizeLines); return (
{ if (typeof line === 'boolean') return {}; return highlightLines.has(line) ? ({ 'data-line-number': `${line}`, 'data-highlight': 'true', } as any) : ({ 'data-line-number': `${line}` } as any); }} customStyle={{ padding: '0.8rem' }} > {value} {showCopy && (
)}
); } const code: NodeRenderer = (node) => { return ( ); }; function isColor(maybeColorHash: string): string | undefined { if (!maybeColorHash || maybeColorHash.length > 9) return undefined; if (!new Set([4, 7, 9]).has(maybeColorHash.length)) return undefined; const match = /^#([0-9A-Fa-f]{3,8})$/.exec(maybeColorHash); if (!match) return undefined; const color = match[1]; return color; } const inlineCode: NodeRenderer = (node, children) => { if (isColor(node.value)) { return ( {children} ); } return {children}; }; const CODE_RENDERERS = { code, inlineCode, }; export default CODE_RENDERERS;