import React from 'react';
import clsx from 'clsx';
import { useThemeConfig, usePrismTheme } from '@docusaurus/theme-common';
import {
parseCodeBlockTitle,
parseLanguage,
parseLines,
containsLineNumbers,
useCodeWordWrap,
} from '@docusaurus/theme-common/internal';
import { Highlight } from 'prism-react-renderer';
import Line from '@theme/CodeBlock/Line';
import CopyButton from '@theme/CodeBlock/CopyButton';
import WordWrapButton from '@theme/CodeBlock/WordWrapButton';
import Container from '@theme/CodeBlock/Container';
import { CiFileOn } from "react-icons/ci";
import styles from './styles.module.css';
import Link from '@docusaurus/Link';
function normalizeLanguage(language) {
return language?.toLowerCase();
}
export default function CodeBlockString({
children,
className: blockClassName = '',
metastring,
title: titleProp,
showLineNumbers: showLineNumbersProp,
language: languageProp,
}) {
const {
prism: { defaultLanguage, magicComments },
} = useThemeConfig();
const language = normalizeLanguage(
languageProp ?? parseLanguage(blockClassName) ?? defaultLanguage,
);
const prismTheme = usePrismTheme();
const wordWrap = useCodeWordWrap();
let title = parseCodeBlockTitle(metastring) || titleProp;
const fileRegex = /<file\s*\/>/;
let isFileIconEnabled = false;
if (fileRegex.test(title)) {
isFileIconEnabled = true;
title = title.replace(fileRegex, '')
} const { lineClassNames, code } = parseLines(children, {
metastring,
language,
magicComments,
});
const showLineNumbers =
showLineNumbersProp ?? containsLineNumbers(metastring);
const regexExtractLink = /link="([^"]+)"/;
const match = `${metastring}`.match(regexExtractLink);
if (match) {
const linkValue = match[1];
title = <Link href={linkValue}> {title}</Link>
} else {
// console.log('Link not found in the input string.');
}
return (
<Container
as="div"
className={clsx(
blockClassName,
language &&
!blockClassName.includes(`language-${language}`) &&
`language-${language}`,
)}>
{title && <div className={styles.codeBlockTitle}>
{isFileIconEnabled ? <CiFileOn className='codeTitleIcon' /> : null}
{title}
</div>}
<div className={styles.codeBlockContent}>
<Highlight theme={prismTheme} code={code} language={language ?? 'text'}>
{({ className, style, tokens, getLineProps, getTokenProps }) => (
<pre
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
tabIndex={0}
ref={wordWrap.codeBlockRef}
className={clsx(className, styles.codeBlock, 'thin-scrollbar')}
style={style}>
<code
className={clsx(
styles.codeBlockLines,
showLineNumbers && styles.codeBlockLinesWithNumbering,
)}>
{tokens.map((line, i) => (
<Line
key={i}
line={line}
getLineProps={getLineProps}
getTokenProps={getTokenProps}
classNames={lineClassNames[i]}
showLineNumbers={showLineNumbers}
/>
))}
</code>
</pre>
)}
</Highlight>
<div className={styles.buttonGroup}>
{(wordWrap.isEnabled || wordWrap.isCodeScrollable) && (
<WordWrapButton
className={styles.codeButton}
onClick={() => wordWrap.toggle()}
isEnabled={wordWrap.isEnabled}
/>
)}
<CopyButton className={styles.codeButton} code={code} />
</div>
</div>
</Container>
);
}