Markdown增强(echarts等插件)

前言

在markdown 语法中我们可以实现标题、表格、图片等功能的实现,但同样有一些定制化的表现形式难以在markdown中实现,最近就遇到一个需求要在markdown渲染器中展示图表,搜阅了很多文档并没有找到现成的实现方法,最终在react-mardown官方文档中受到启发并实现了这个需求。

react-markdown

react-markdown 是React生态中的一个三方库,主要功能是渲染markdown语法的文本为markdown的预览模式。 使用方法也比较简单:

tsx 复制代码
import React, { FC } from 'react';
import Markdown from 'react-markdown';
import styled from 'styled-components';
interface MDPropsType {}
/** */
export const MD: FC<MDPropsType> = (props) => {
	const markdown = `
# 前言
在markdown 语法中我们可以实现标题、表格、图片等功能的实现,但同样有一些定制化的表现形式难以在markdown中实现,最近就遇到一个需求要在markdown渲染器中展示图表,搜阅了很多文档并没有找到现成的实现方法,最终在[react-mardown官方文档](https://github.com/remarkjs/react-markdown)中受到启发并实现了这个需求。

## react-markdown
react-markdown 是React生态中的一个三方库,主要功能是渲染markdown语法的文本为markdown的预览模式。
使用方法也比较简单:
\`\`\`js
console.log("Hello, Word!")
\`\`\`
	`;
	return (
		<MDContain>
			<Markdown children={markdown}></Markdown>
		</MDContain>
	);
};
//style_components
const MDContain = styled.div`
	width: 100%;
	height: 100%;
`;

这里的显示结果是没有样式的,可以去引用三方的样式或者说是自己去写样式

在此处我采用的是引用github markdown的样式

这里可以看到代码块是没有样式和高亮的
react-mardown官方文档中有提到解决方案

当然,其他插件也可以使用:

按照官方文档的指引去完善代码

  1. npm i remark-gfm react-syntax-highlighter --save-dev
  2. 完善代码
tsx 复制代码
import React, { FC } from 'react';
import Markdown from 'react-markdown';
import styled from 'styled-components';
import remarkGfm from 'remark-gfm';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { atomDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
interface MDPropsType {}
/** */
export const MD: FC<MDPropsType> = (props) => {
  const markdown = `
# 前言
在markdown 语法中我们可以实现标题、表格、图片等功能的实现,但同样有一些定制化的表现形式难以在markdown中实现,最近就遇到一个需求要在markdown渲染器中展示图表,搜阅了很多文档并没有找到现成的实现方法,最终在[react-mardown官方文档](https://github.com/remarkjs/react-markdown)中受到启发并实现了这个需求。

## react-markdown
react-markdown 是React生态中的一个三方库,主要功能是渲染markdown语法的文本为markdown的预览模式。
使用方法也比较简单:
\`\`\`js
console.log("Hello, Word!")
\`\`\`
	`;
  return (
    <MDContain>
      <Markdown
        children={markdown}
        remarkPlugins={[remarkGfm]}
        components={{
          code(props) {
          const { children, className, node, ...rest } = props;
          const match = /language-(\w+)/.exec(className || '');
          return match ? (
            <SyntaxHighlighter
               {...rest}
               PreTag='div'
               children={String(children).replace(/\n$/, '')}
               language={match[1]}
               style={atomDark}
             />
             ) : (
             <code {...rest} className={className}>
               {children}
             </code>
             );
           }
         }}></Markdown>
       </MDContain>
     );
};
//style_components
const MDContain = styled.div`
	width: 100%;
	height: 100%;
`;

结果是这个样子的

观察代码高亮的插件实现不难发现其中的原理

在components对象的的code方法上可以通过className去捕获对应的语,这里我们用```echarts来定义语言

而children就是代码块里面的内容,这里我们用json来保存图标数据

return 会返回如何渲染

那么我们可以写一个Echarts组件接收 option 内容去渲染图表

tsx 复制代码
import React, { FC, useEffect, useRef } from 'react';
import Markdown from 'react-markdown';
import styled from 'styled-components';
import remarkGfm from 'remark-gfm';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { atomDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
import * as echarts from 'echarts';
interface MDPropsType {}
/** */
export const MD: FC<MDPropsType> = (props) => {
  const markdown = `
# 前言
在markdown 语法中我们可以实现标题、表格、图片等功能的实现,但同样有一些定制化的表现形式难以在markdown中实现,最近就遇到一个需求要在markdown渲染器中展示图表,搜阅了很多文档并没有找到现成的实现方法,最终在[react-mardown官方文档](https://github.com/remarkjs/react-markdown)中受到启发并实现了这个需求。

## react-markdown
react-markdown 是React生态中的一个三方库,主要功能是渲染markdown语法的文本为markdown的预览模式。
使用方法也比较简单:
\`\`\`js
console.log("Hello, Word!")
\`\`\`
\`\`\`echarts
{"xAxis":{"type":"category","data":["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]},"yAxis":{"type":"value"},"series":[{"data":[120,200,150,80,70,110,130],"type":"bar"}]}
\`\`\`
  `;
  return (
    <MDContain>
      <Markdown
        children={markdown}
        remarkPlugins={[remarkGfm]}
        components={{
          code(props) {
            const { children, className, node, ...rest } = props;
            const match = /language-(\w+)/.exec(className || '');
            if (!match) {
              return (
                <code {...rest} className={className}>
                  {children}
                </code>
              );
            }
            if (match[1] === 'echarts') {
              return <ChartsRende option={JSON.parse(children)}></ChartsRende>;
            }
            return (
              <SyntaxHighlighter
                {...rest}
                PreTag='div'
                children={String(children).replace(/\n$/, '')}
                language={match[1]}
                style={atomDark}
              />
            );
          }
        }}></Markdown>
    </MDContain>
  );
};
//style_components
const MDContain = styled.div`
  width: 100%;
  height: 100%;
`;
const ChartsRende: React.FC<{ option: echarts.EChartsOption }> = ({ option }) => {
  const chartRef = useRef<echarts.ECharts>();
  const domRef = useRef<HTMLElement>();
  useEffect(() => {
    chartRef.current = echarts.init(domRef.current);
    chartRef.current.setOption(option);
  }, [option]);

  return <div ref={domRef} style={{ height: 300 }} className='chart_contain'></div>;
};

这样就得出了在markdown中显示的Echarts

相关推荐
小信丶14 分钟前
解决 pnpm dev 报错:系统禁止运行脚本的问题
前端·vue.js·windows·npm
૮・ﻌ・21 分钟前
Vue3:组合式API、Vue3.3新特性、Pinia
前端·javascript·vue3
前端不太难21 分钟前
RN + TypeScript 项目越写越乱?如何规范架构?
前端·javascript·typescript
神算大模型APi--天枢64622 分钟前
全栈自主可控:国产算力平台重塑大模型后端开发与部署生态
大数据·前端·人工智能·架构·硬件架构
苏打水com22 分钟前
第十五篇:Day43-45 前端性能优化进阶——从“可用”到“极致”(对标职场“高并发场景优化”需求)
前端·css·vue·html·js
@大迁世界30 分钟前
08.CSS if() 函数
前端·css
Moment36 分钟前
小米不仅造车,还造模型?309B参数全开源,深度思考完胜DeepSeek 🐒🐒🐒
前端·人工智能·后端
苏打水com40 分钟前
第十六篇:Day46-48 前端安全进阶——从“漏洞防范”到“安全体系”(对标职场“攻防实战”需求)
前端·javascript·css·vue.js·html
5C2442 分钟前
从思想到实践:前端工程化体系与 Webpack 构建架构深度解析
前端·前端工程化
咕噜企业分发小米1 小时前
如何平衡服务器内存使用率和系统稳定性?
java·服务器·前端