mirror of
				https://github.com/langgenius/dify.git
				synced 2025-10-31 19:03:09 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			89 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			89 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import ReactMarkdown from 'react-markdown'
 | |
| import 'katex/dist/katex.min.css'
 | |
| import RemarkMath from 'remark-math'
 | |
| import RemarkBreaks from 'remark-breaks'
 | |
| import RehypeKatex from 'rehype-katex'
 | |
| import RemarkGfm from 'remark-gfm'
 | |
| import RehypeRaw from 'rehype-raw'
 | |
| import { flow } from 'lodash-es'
 | |
| import cn from '@/utils/classnames'
 | |
| import { customUrlTransform, preprocessLaTeX, preprocessThinkTag } from './markdown-utils'
 | |
| import {
 | |
|   AudioBlock,
 | |
|   CodeBlock,
 | |
|   Img,
 | |
|   Link,
 | |
|   MarkdownButton,
 | |
|   MarkdownForm,
 | |
|   Paragraph,
 | |
|   ScriptBlock,
 | |
|   ThinkBlock,
 | |
|   VideoBlock,
 | |
| } from '@/app/components/base/markdown-blocks'
 | |
| 
 | |
| /**
 | |
|  * @fileoverview Main Markdown rendering component.
 | |
|  * This file was refactored to extract individual block renderers and utility functions
 | |
|  * into separate modules for better organization and maintainability as of [Date of refactor].
 | |
|  * Further refactoring candidates (custom block components not fitting general categories)
 | |
|  * are noted in their respective files if applicable.
 | |
|  */
 | |
| 
 | |
| export function Markdown(props: { content: string; className?: string; customDisallowedElements?: string[] }) {
 | |
|   const latexContent = flow([
 | |
|     preprocessThinkTag,
 | |
|     preprocessLaTeX,
 | |
|   ])(props.content)
 | |
| 
 | |
|   return (
 | |
|     <div className={cn('markdown-body', '!text-text-primary', props.className)}>
 | |
|       <ReactMarkdown
 | |
|         remarkPlugins={[
 | |
|           RemarkGfm,
 | |
|           [RemarkMath, { singleDollarTextMath: false }],
 | |
|           RemarkBreaks,
 | |
|         ]}
 | |
|         rehypePlugins={[
 | |
|           RehypeKatex,
 | |
|           RehypeRaw as any,
 | |
|           // The Rehype plug-in is used to remove the ref attribute of an element
 | |
|           () => {
 | |
|             return (tree: any) => {
 | |
|               const iterate = (node: any) => {
 | |
|                 if (node.type === 'element' && node.properties?.ref)
 | |
|                   delete node.properties.ref
 | |
| 
 | |
|                 if (node.type === 'element' && !/^[a-z][a-z0-9]*$/i.test(node.tagName)) {
 | |
|                   node.type = 'text'
 | |
|                   node.value = `<${node.tagName}`
 | |
|                 }
 | |
| 
 | |
|                 if (node.children)
 | |
|                   node.children.forEach(iterate)
 | |
|               }
 | |
|               tree.children.forEach(iterate)
 | |
|             }
 | |
|           },
 | |
|         ]}
 | |
|         urlTransform={customUrlTransform}
 | |
|         disallowedElements={['iframe', 'head', 'html', 'meta', 'link', 'style', 'body', ...(props.customDisallowedElements || [])]}
 | |
|         components={{
 | |
|           code: CodeBlock,
 | |
|           img: Img,
 | |
|           video: VideoBlock,
 | |
|           audio: AudioBlock,
 | |
|           a: Link,
 | |
|           p: Paragraph,
 | |
|           button: MarkdownButton,
 | |
|           form: MarkdownForm,
 | |
|           script: ScriptBlock as any,
 | |
|           details: ThinkBlock,
 | |
|         }}
 | |
|       >
 | |
|         {/* Markdown detect has problem. */}
 | |
|         {latexContent}
 | |
|       </ReactMarkdown>
 | |
|     </div>
 | |
|   )
 | |
| }
 | 
