import * as React from 'react'; import type { PrismLanguage } from './languages-available.js'; import { Prism } from './prism.js'; import type { Theme } from './themes.js'; type PrismToken = InstanceType; export interface CodeBlockProps extends React.ComponentPropsWithoutRef<'pre'> { lineNumbers?: boolean; /** * This applies a certain font family on all elements render in this component, * it is mostly meant to override a global font that has already been used with * our `` component */ fontFamily?: string; theme: Theme; language: PrismLanguage; code: string; } const stylesForToken = (token: PrismToken, theme: Theme) => { let styles = { ...theme[token.type] }; const aliases = Array.isArray(token.alias) ? token.alias : [token.alias]; for (const alias of aliases) { styles = { ...styles, ...theme[alias] }; } return styles; }; const CodeBlockLine = ({ token, theme, inheritedStyles, }: { token: string | PrismToken; theme: Theme; inheritedStyles?: React.CSSProperties; }) => { if (token instanceof Prism.Token) { const styleForToken = { ...inheritedStyles, ...stylesForToken(token, theme), }; if (token.content instanceof Prism.Token) { return ( ); } if (typeof token.content === 'string') { return {token.content}; } return ( <> {token.content.map((subToken, i) => ( ))} ); } return ( {token.replaceAll(' ', '\xA0\u200D\u200B')} ); }; export const CodeBlock = React.forwardRef( ({ code, fontFamily, lineNumbers, theme, language, ...rest }, ref) => { const languageGrammar = Prism.languages[language]; if (typeof languageGrammar === 'undefined') { throw new Error( `CodeBlock: There is no language defined on Prism called ${language}`, ); } const lines = code.split(/\r\n|\r|\n/gm); const tokensPerLine = lines.map((line) => Prism.tokenize(line, languageGrammar), ); return (
        
          {tokensPerLine.map((tokensForLine, lineIndex) => (
            
              {lineNumbers ? (
                
                  {lineIndex + 1}
                
              ) : null}

              {tokensForLine.map((token, i) => (
                
              ))}
              
))}
); }, ); CodeBlock.displayName = 'CodeBlock';