import { FC, CSSProperties, ReactNode } from 'react' import ReactMarkdown from 'react-markdown' import remarkGfm from 'remark-gfm' import remarkMath from 'remark-math' import rehypeKatex from 'rehype-katex' import rehypeRaw from 'rehype-raw' import { useTranslation } from 'next-i18next' import { LightAsync as SyntaxHighlighter } from 'react-syntax-highlighter' import { tomorrowNight } from 'react-syntax-highlighter/dist/cjs/styles/hljs' import 'katex/dist/katex.min.css' import useFileContent from '../../utils/fetchOnMount' import FourOhFour from '../FourOhFour' import Loading from '../Loading' import DownloadButtonGroup from '../DownloadBtnGtoup' import { DownloadBtnContainer, PreviewContainer } from './Containers' const MarkdownPreview: FC<{ file: any path: string standalone?: boolean }> = ({ file, path, standalone = true }) => { // The parent folder of the markdown file, which is also the relative image folder const parentPath = standalone ? path.substring(0, path.lastIndexOf('/')) : path const { response: content, error, validating } = useFileContent(`/api/raw/?path=${parentPath}/${file.name}`, path) const { t } = useTranslation() // Check if the image is relative path instead of a absolute url const isUrlAbsolute = (url: string | string[]) => url.indexOf('://') > 0 || url.indexOf('//') === 0 // Custom renderer: const customRenderer = { // img: to render images in markdown with relative file paths img: ({ alt, src, title, width, height, style, }: { alt?: string src?: string title?: string width?: string | number height?: string | number style?: CSSProperties }) => { return ( // eslint-disable-next-line @next/next/no-img-element {alt} ) }, // code: to render code blocks with react-syntax-highlighter code({ className, children, inline, ...props }: { className?: string | undefined children: ReactNode inline?: boolean }) { if (inline) { return ( {children} ) } const match = /language-(\w+)/.exec(className || '') return ( {String(children).replace(/\n$/, '')} ) }, } if (error) { return ( ) } if (validating) { return ( <> {standalone && ( )} ) } return (
{/* Using rehypeRaw to render HTML inside Markdown is potentially dangerous, use under safe environments. (#18) */} {content}
{standalone && ( )}
) } export default MarkdownPreview