@@ -4,6 +4,32 @@ import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
4
4
import { oneDark } from "react-syntax-highlighter/dist/esm/styles/prism" ;
5
5
import { cn } from "@/lib/utils" ;
6
6
import { CopyToClipboard } from "./CopyToClipboard" ;
7
+ import hljs from "highlight.js" ;
8
+
9
+ const LANGUAGES_SUBSET_DETECTION = [
10
+ "c" ,
11
+ "cpp" ,
12
+ "csharp" ,
13
+ "css" ,
14
+ "elixir" ,
15
+ "go" ,
16
+ "groovy" ,
17
+ "haskell" ,
18
+ "html" ,
19
+ "java" ,
20
+ "javascript" ,
21
+ "json" ,
22
+ "kotlin" ,
23
+ "markdown" ,
24
+ "php" ,
25
+ "python" ,
26
+ "ruby" ,
27
+ "rust" ,
28
+ "scala" ,
29
+ "sql" ,
30
+ "typescript" ,
31
+ "yaml" ,
32
+ ] ;
7
33
8
34
interface Props {
9
35
children : string ;
@@ -12,85 +38,58 @@ interface Props {
12
38
13
39
const customStyle = {
14
40
...oneDark ,
41
+ 'code[class*="language-"]' : {
42
+ ...oneDark [ 'code[class*="language-"]' ] ,
43
+ background : "none" ,
44
+ } ,
15
45
'pre[class*="language-"]' : {
16
46
...oneDark [ 'pre[class*="language-"]' ] ,
17
- whiteSpace : "pre-wrap" ,
18
47
background : "#1a1b26" ,
19
48
padding : "1.5rem" ,
20
49
borderRadius : "0.5rem" ,
21
- margin : "1.5rem 0" ,
22
- fontSize : "10px" ,
23
- width : "80%" , // Ensure the block takes full width
50
+ width : "100%" ,
24
51
position : "relative" ,
52
+ boxSizing : "border-box" ,
25
53
} ,
26
54
} ;
27
-
28
55
export function Markdown ( { children, className = "" } : Props ) {
56
+ SyntaxHighlighter . supportedLanguages = LANGUAGES_SUBSET_DETECTION ;
29
57
return (
30
58
< ReactMarkdown
31
59
components = { {
32
- /* eslint-disable @typescript-eslint/no-explicit-any */
33
- code ( { className, children, ...props } : any ) {
60
+ code ( { className, children, ...props } ) {
61
+ const detectedLanguage =
62
+ hljs . highlightAuto ( children , LANGUAGES_SUBSET_DETECTION ) . language ??
63
+ "plaintext" ;
34
64
const match = / l a n g u a g e - ( \w + ) / . exec ( className || "" ) ;
35
- const inline = ! match ;
36
- return ! inline ? (
37
- < div className = "relative group w-full ml-0 px -4" >
65
+ const language = match ? match [ 1 ] : detectedLanguage ;
66
+ return (
67
+ < div className = "relative group w-full ml-0 my -4" >
38
68
< SyntaxHighlighter
39
- style = { {
40
- ...customStyle ,
41
- 'pre[class*="language-"]' : {
42
- ...oneDark [ 'pre[class*="language-"]' ] ,
43
- background : "#1a1b26" ,
44
- fontSize : "10x" ,
45
- whiteSpace : "pre-wrap" ,
46
- padding : "1.5rem" ,
47
- borderRadius : "0.5rem" ,
48
- margin : "1.5rem 0" ,
49
- position : "relative" , // Critical for clipboard positioning
50
- width : "100%" , // Ensure full width of parent container
51
- boxSizing : "border-box" , // Prevent padding overflow
52
- } ,
53
- } }
54
- language = { match [ 1 ] }
69
+ style = { customStyle }
70
+ supportedLanguages = { LANGUAGES_SUBSET_DETECTION }
71
+ language = { language }
55
72
PreTag = "div"
56
- className = "rounded-lg overflow-hidden shadow-lg text-sm"
57
- showLineNumbers = { false }
58
- wrapLines = { true }
73
+ className = "rounded-lg overflow-hidden shadow-lg text-sm my-6 whitespace-normal"
74
+ wrapLines
59
75
{ ...props }
60
76
>
61
77
{ String ( children ) . replace ( / \n $ / , "" ) }
62
78
</ SyntaxHighlighter >
63
- < CopyToClipboard text = { String ( children ) . replace ( / \n $ / , "" ) } />
79
+ { match && (
80
+ < CopyToClipboard text = { String ( children ) . replace ( / \n $ / , "" ) } />
81
+ ) }
64
82
</ div >
65
- ) : (
66
- < SyntaxHighlighter
67
- style = { {
68
- ...customStyle ,
69
- 'pre[class*="language-"]' : {
70
- ...oneDark [ 'pre[class*="language-"]' ] ,
71
- fontSize : "10x" ,
72
- whiteSpace : "pre-wrap" ,
73
- padding : "1.5rem" ,
74
- borderRadius : "0.5rem" ,
75
- margin : "1.5rem 0" ,
76
- position : "relative" , // Critical for clipboard positioning
77
- width : "100%" , // Ensure full width of parent container
78
- boxSizing : "border-box" , // Prevent padding overflow
79
- } ,
80
- } }
81
- PreTag = "div"
82
- className = "rounded-lg overflow-hidden shadow-lg text-sm"
83
- showLineNumbers = { false }
84
- wrapLines = { true }
85
- { ...props }
86
- >
87
- { children }
88
- </ SyntaxHighlighter >
89
83
) ;
90
84
} ,
91
85
p ( { children } ) {
92
86
return (
93
- < p className = { cn ( "text-gray-600 leading-relaxed mb-4" , className ) } >
87
+ < p
88
+ className = { cn (
89
+ "text-gray-600 leading-relaxed mt-6 mb-3" ,
90
+ className ,
91
+ ) }
92
+ >
94
93
{ children }
95
94
</ p >
96
95
) ;
0 commit comments