File size: 3,467 Bytes
97cab0c
 
 
117cfaa
97cab0c
 
 
 
 
 
 
 
 
 
 
 
 
117cfaa
97cab0c
 
 
 
 
 
 
117cfaa
97cab0c
 
25e8265
97cab0c
 
 
 
 
117cfaa
5541427
117cfaa
 
97cab0c
 
 
 
 
117cfaa
 
97cab0c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
import { oneLight } from 'react-syntax-highlighter/dist/esm/styles/prism'

interface MarkdownRendererProps {
  content: string
}

const MarkdownRenderer = ({ content }: MarkdownRendererProps) => {
  const cleanContent = content
    .replace(/^---\s*\n.*?\n---\s*\n/s, '')
    .replace(/<[^>]*>/g, '')

  return (
    <ReactMarkdown
      remarkPlugins={[remarkGfm]}
      disallowedElements={['script', 'style', 'iframe', 'object', 'embed']}
      unwrapDisallowed={true}
      components={{
        code: ({ className, children, ...props }: any) => {
          const match = /language-(\w+)/.exec(className || '')
          const isInline = !match
          return !isInline ? (
            <SyntaxHighlighter
              style={oneLight}
              language={match[1]}
              PreTag="div"
              className="rounded-md my-4 border  text-sm"
              {...props}
            >
              {String(children).replace(/\n$/, '')}
            </SyntaxHighlighter>
          ) : (
            <code
              className="bg-gray-100 px-1 py-0.5 rounded-sm text-sm font-mono"
              {...props}
            >
              {children}
            </code>
          )
        },
        a: ({ children, href }) => (
          <a
            href={href}
            className="text-blue-600 hover:text-blue-800 underline"
            target="_blank"
            rel="noopener noreferrer"
          >
            {children}
          </a>
        ),
        table: ({ children }) => (
          <div className="overflow-x-auto">
            <table className="min-w-full divide-y divide-gray-200">
              {children}
            </table>
          </div>
        ),
        thead: ({ children }) => (
          <thead className="bg-gray-50">{children}</thead>
        ),
        tbody: ({ children }) => (
          <tbody className="bg-white divide-y divide-gray-200">
            {children}
          </tbody>
        ),
        th: ({ children }) => (
          <th className="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider border border-gray-300">
            {children}
          </th>
        ),
        td: ({ children }) => (
          <td className="px-3 py-2 whitespace-nowrap text-sm text-gray-900 border border-gray-300">
            {children}
          </td>
        ),
        ul: ({ children }) => (
          <ul className="list-disc list-inside space-y-1 ml-4 mb-4">
            {children}
          </ul>
        ),
        ol: ({ children }) => (
          <ol className="list-decimal list-inside space-y-1 ml-4 mb-4">
            {children}
          </ol>
        ),
        li: ({ children }) => (
          <li className="text-sm text-gray-900">{children}</li>
        ),
        h1: ({ children }) => (
          <h1 className="text-xl font-semibold text-gray-900 mb-3 mt-4">
            {children}
          </h1>
        ),
        h2: ({ children }) => (
          <h2 className="text-lg font-semibold text-gray-900 mb-2 mt-3">
            {children}
          </h2>
        ),
        h3: ({ children }) => (
          <h3 className="text-base font-semibold text-gray-900 mb-2 mt-3">
            {children}
          </h3>
        )
      }}
    >
      {cleanContent}
    </ReactMarkdown>
  )
}

export default MarkdownRenderer