如何在 nextjs 里面使用 markdown 格式输出?

需要使用一个叫“react-markdown”的库。

首先安装库:

npm i react-markdown
Bash

import 库:

import ReactMarkdown from 'react-markdown'; 
JSX

使用 markdown 的模块:

<ReactMarkdown>{yourContent}</ReactMarkdown>
JSX

如果需要使用 html 模块,比如<br/>,需要添加 Plugins rehypeRaw

<ReactMarkdown rehypePlugins={[rehypeRaw]}>{yourContent}</ReactMarkdown>
JSX

如果需要使用不常用的markdown语法,需要使用插件remark-gfm,用法与其他 Plugins 一致。

<ReactMarkdown remarkPlugins={[remarkGfm]}>{yourContent}</ReactMarkdown>
JSX

官网解释remark-gfm

<ReactMarkdown> 支持的语法: 

ablockquotebrcodeemh1h2h3h4h5h6hrimgliolpprestrong, and ul.

remark-gfm Plugin 支持的语法: 

delinputtabletbodytdththead, and tr.


表格输出

除了使用 remark-gfm Plugin 外,还需要额外添加 CSS 语法。这样一来,才会显示表格的边框。

以 openai 的输出为例,主要影响的是th表头和td表格内容。需要添加在globals.css里面:

th {
  background-color: #b3e5fc; /* 表头是浅蓝色的 */
  color: #333;
  font-weight: bold;
  text-align: center; /* 居中 */
}

td {
  text-align: center;
}
CSS


使用 TailwindCSS 后 markdown 失效

如果你在使用 TailwindCSS,请注意 markdown 效果不能正常显示。因为 TailwindCSS 会改变所有 html 的元素效果,可以参考这个帖子

解决方法是在 globals.css 新增一个类,叫做 markdown,代码如下:

 .markdown > * {
  all: revert;
}
JSX

这个代码会消除已有的 html 效果,所以只需要在 ReactMarkdown 上添加这个类即可:

<ReactMarkdown className='markdown'>{messageContent}</ReactMarkdown>
JSX


如何显示 code block

code block 需要用到 react-syntax-highlighter,首先是安装:

npm install react-syntax-highlighter
Bash

需要 import 两个库,一个是 react-syntax-highlighter,一个是代码风格:

import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'
import {vscDarkPlus} from 'react-syntax-highlighter/dist/esm/styles/prism'
JSX

在 return 里面,输出以下代码:

<ReactMarkdown className='markdown' rehypePlugins={[rehypeRaw]} 
   components={{
      code({node, inline, className, children, ...props}) {
      const match = /language-(\w+)/.exec(className || '')
      return !inline && match ? (
        <SyntaxHighlighter
          {...props}
          children={String(children).replace(/\n$/, '')}
          style={vscDarkPlus}
          language={match[1]}
          PreTag="div"
        />
      ) : (
        <code {...props} className={className}>
          {children}
        </code>
      )
      }
    }}
>{messageContent}</ReactMarkdown>
JSX

这样可以实现检测出代码时,以代码的形式输出,效果如下图:

以上代码主要参考 react-markdown 官网中 react-syntax-highlighter 模块。

代码换行

如何让代码自动换行:

wrapLongLines={true}

react-syntax-highlighter 的参数可查阅github链接。

代码:

<SyntaxHighlighter
  {...props}
  children={String(children).replace(/\n$/, '')}
  style={vscDarkPlus}
  language={match[1]}
  PreTag="div"
  wrapLongLines={true}
/>
JSX

效果如下:

参考链接:

react-markdown 官网

https://www.npmjs.com/package/react-markdown?activeTab=readme

react-syntax-highlighter style 预览:

https://react-syntax-highlighter.github.io/react-syntax-highlighter/demo/prism.html

react-syntax-highlighter style 各类别名称:

https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/AVAILABLE_STYLES_PRISM.MD

React Markdown: A Thorough Guide With Markdown Examples:

https://www.copycat.dev/blog/react-markdown/

react-syntax-highlighter 个人经验:

https://medium.com/young-developer/react-markdown-code-and-syntax-highlighting-632d2f9b4ada

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注