11import { FormEvent , useContext , useEffect , useMemo , useState } from 'react'
2- import ReactMarkdown from 'react-markdown'
2+ import ReactMarkdown , { Components , Options } from 'react-markdown'
33import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
44import { nord } from 'react-syntax-highlighter/dist/esm/styles/prism'
55import { Checkbox , DefaultButton , Dialog , FontIcon , Stack , Text } from '@fluentui/react'
@@ -228,19 +228,38 @@ export const Answer = ({ answer, onCitationClicked }: Props) => {
228228 )
229229 }
230230
231- const components = {
232- code ( { node, ...props } : { node : any ; [ key : string ] : any } ) {
233- let language
234- if ( props . className ) {
235- const match = props . className . match ( / l a n g u a g e - ( \w + ) / )
236- language = match ? match [ 1 ] : undefined
231+ const components : Components = {
232+ a : ( { href, children, ...props } ) => (
233+ < a href = { href } target = "_blank" rel = "noopener noreferrer" { ...props } >
234+ { children }
235+ </ a >
236+ ) ,
237+ code ( { inline, className, children, ...props } : {
238+ inline ?: boolean ;
239+ className ?: string ;
240+ children ?: React . ReactNode ;
241+ [ key : string ] : any
242+ } ) {
243+ const match = / l a n g u a g e - ( \w + ) / . exec ( className || '' ) ;
244+ // Handle inline and block code rendering
245+ if ( inline ) {
246+ return (
247+ < code className = { className } { ...props } >
248+ { children }
249+ </ code >
250+ ) ;
251+ } else if ( match ) {
252+ return (
253+ < SyntaxHighlighter
254+ style = { nord }
255+ language = { match [ 1 ] }
256+ PreTag = "div"
257+ { ...props }
258+ >
259+ { String ( children ) . replace ( / \n $ / , '' ) }
260+ </ SyntaxHighlighter >
261+ ) ;
237262 }
238- const codeString = node . children [ 0 ] . value ?? ''
239- return (
240- < SyntaxHighlighter style = { nord } language = { language } PreTag = "div" { ...props } >
241- { codeString }
242- </ SyntaxHighlighter >
243- )
244263 }
245264 }
246265 return (
@@ -249,18 +268,17 @@ export const Answer = ({ answer, onCitationClicked }: Props) => {
249268 < Stack . Item >
250269 < Stack horizontal grow >
251270 < Stack . Item grow >
252- < ReactMarkdown
253- linkTarget = "_blank"
254- remarkPlugins = { [ remarkGfm , supersub ] }
255- rehypePlugins = { [ rehypeRaw ] }
256- children = {
257- SANITIZE_ANSWER
258- ? DOMPurify . sanitize ( parsedAnswer . markdownFormatText , { ALLOWED_TAGS : XSSAllowTags } )
259- : parsedAnswer . markdownFormatText
260- }
261- className = { styles . answerText }
262- components = { components }
263- />
271+ < ReactMarkdown
272+ remarkPlugins = { [ remarkGfm , supersub ] }
273+ rehypePlugins = { [ rehypeRaw ] }
274+ children = {
275+ SANITIZE_ANSWER
276+ ? DOMPurify . sanitize ( parsedAnswer . markdownFormatText , { ALLOWED_TAGS : XSSAllowTags , ALLOWED_ATTR : [ 'href' , 'target' , 'rel' ] } )
277+ : parsedAnswer . markdownFormatText
278+ }
279+ className = { styles . answerText }
280+ components = { components }
281+ />
264282 </ Stack . Item >
265283 < Stack . Item className = { styles . answerHeader } >
266284 { FEEDBACK_ENABLED && answer . message_id !== undefined && (
0 commit comments