React markdown 编辑器

2023-05-16

react-markdown 是一款 github 上开源的适用于 reactmarkdown 组件,可以基本实现 markdown 的功能,且可以根据自己实际应用定制的 remark 组件。

安装

安装 markdown 预览插件 react-markdown

npm install react-markdown

或者:

yarn add react-markdown

安装 markdown 编辑器插件 for-editor

yarn add for-editor

或者:

npm install for-editor

安装代码高亮插件包 react-syntax-highlighter

npm install react-syntax-highlighter

或者:

yarn add react-syntax-highlighter

安装 remark-math

npm install remark-math

或者:

yarn add remark-math

安装 rehype-katex

npm install rehype-katex

或者:

yarn add rehype-katex

安装 rehype-raw

npm install rehype-raw

或者:

yarn add rehype-raw

组件依赖

组件涉及的依赖及版本 package.json

{
  "dependencies": {
    "antd": "^4.16.10",
    "less": "^4.1.1",
    "less-loader": "4.0.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "^5.2.0",
    "for-editor": "^0.3.5", // Markdown编辑
    "react-markdown": "^8.0.7", // Markdown预览
    "rehype-katex": "^6.0.2", // 数学公式katex语法
    "rehype-raw": "^6.1.1", // 支持HTML语法解析
    "remark-math": "^5.1.1", // 支持数学公式 
    "react-scripts": "4.0.3",
    "typescript": "^5.0.4",
  }
}
  • for-editormarkdown 编辑器
  • react-markdownmarkdown 内容预览及展示
  • rehype-raw:解析 HTML 文本富文本内容
  • remark-math、rehype-katex:数学公式支持及语法解析使用(数学公式的样式展示需要 katex.min.css 文件支持)

基本使用

编辑器 for-editor

属性

名称类型默认值描述
valueString-输入框内容
placeholderString开始编辑…占位文本
lineNumBooleantrue是否显示行号
styleObject-编辑器样式
heightString600px编辑器高度
previewBooleanfalse预览模式
expandBooleanfalse全屏模式
subfieldBooleanfalse双栏模式(预览模式激活下有效)
languageStringzh-CN语言(支持 zh-CN:中文简体, en:英文)
toolbarObject如下自定义工具栏
/*
  默认工具栏按钮全部开启, 传入自定义对象
  例如: {
    h1: true, // h1
    code: true, // 代码块
    preview: true, // 预览
  }
  此时, 仅仅显示此三个功能键
  注:传入空对象则不显示工具栏
 */

toolbar: {
  h1: true, // h1
  h2: true, // h2
  h3: true, // h3
  h4: true, // h4
  img: true, // 图片
  link: true, // 链接
  code: true, // 代码块
  preview: true, // 预览
  expand: true, // 全屏
  /* v0.0.9 */
  undo: true, // 撤销
  redo: true, // 重做
  save: true, // 保存
  /* v0.2.3 */
  subfield: true, // 单双栏模式
}

事件

名称参数类型默认值描述
onChangeString: valuefunction(e)-内容改变时回调
onSaveString: valuefunction(e)-保存时回调
addImgFile: filefunction(e)-添加图片时回调

快捷键

名称描述
tab两个空格缩进
ctrl+s保存
ctrl+z上一步
ctrl+y下一步

views/md-editor/ 文件夹下面新建 MdEditor.js 文件:

import React, { useState } from "react"
import MdEditor from 'for-editor'

const DemoEditor = () => {
  /** 默认工具栏按钮全部开启, 传入自定义对象
  例如: {
    h1: true, // h1
    code: true, // 代码块
    preview: true, // 预览
  }
  此时, 工具栏只显示此三个功能键(注:传入空对象则不显示工具栏)
  */
  // 工具栏菜单
  const toolbar = {
    h1: true, // h1
    h2: true, // h2
    h3: true, // h3
    h4: true, // h4
    img: true, // 图片
    link: true, // 链接
    code: true, // 代码块
    preview: true, // 预览
    expand: true, // 全屏
    /* v0.0.9 */
    undo: true, // 撤销
    redo: true, // 重做
    save: true, // 保存
    /* v0.2.3 */
    subfield: true, // 单双栏模式
  };

  // 保存Markdown文本内容
  const [mdContent, setMdContent] = useState('')

  // 上传图片
  function uploadImg (file) {
    console.log('file', file);
  };
  // 输入内容改变
  function handleEditorChange (value) {
    console.log('handleChange', value);
    setMdContent(value)
  }
  // 保存输入内容
  function handleEditorSave (value) {
    console.log('handleEditorSave', value);
  }
  return (
    <MdEditor placeholder="请输入Markdown文本" height={600} lineNum={false}
      toolbar={toolbar} value={mdContent} onChange={handleEditorChange} onSave={handleEditorSave} addImg={uploadImg} />
  )
}
export default DemoEditor

App.js 中引入 md-editor.js 文件:

import './assets/css/App.css';
import MdCtxEditor from './views/md-editor/MdEditor';

function App () {
  return (
    <div className="App">
      <MdCtxEditor />
    </div>
  );
}
export default App;

页面效果:
在这里插入图片描述

预览 react-markdown

views/md-editor/ 文件夹下面新建 MdPreview.js 文件:

import React, { useEffect, useState } from "react"
import ReactMarkdown from 'react-markdown'

const DemoPage = () => {
  const [docmentContent, setDocmentContent] = useState('')
  const content = '# This is title 1\n\n## This is title 2\n\n### This is title 3\n\nAnd this is a paragraph\n\n**A paragraph with strong importance**\n\n*A block quote with ~strikethrough~*'
  useEffect(() => {
    setDocmentContent(content)
  }, [])
  return (
    <div className="markdown-body" style={{ padding: '30px', borderRadius: '10px' }}>
      <ReactMarkdown children={docmentContent} />
    </div>
  )
}
export default DemoPage

App.js 中引入 MdPreview.js 文件:

import './assets/css/App.css';
import MdCtxPreview from './views/md-editor/MdPreview';

function App () {
  return (
    <div className="App">
      <MdCtxPreview />
    </div>
  );
}
export default App;

页面效果:
在这里插入图片描述

代码块高亮

修改 MdPreview.js 文件:

import React, { useEffect, useState } from "react"
import ReactMarkdown from 'react-markdown'

import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
// 设置高亮样式
import { xonokai } from 'react-syntax-highlighter/dist/esm/styles/prism'

const Code = {
  code ({ node, inline, className, children, ...props }) {
    const match = /language-(\w+)/.exec(className || '')
    return !inline && match ? (
      <SyntaxHighlighter
        children={String(children).replace(/\n$/, '')}
        style={xonokai}
        language={match[1]}
        PreTag="div"
        {...props}
      />
    ) : (
      <code className={className} {...props}>
        {children}
      </code>
    )
  }
}
const DemoPage = () => {
  const [docmentContent, setDocmentContent] = useState('')
  const content = `This is some JavaScript code:
  ~~~js
  console.log('Hello world!')
  ~~~
  `
  useEffect(() => {
    setDocmentContent(content)
  }, [])
  return (
    <div className="markdown-body" style={{ padding: '30px', borderRadius: '10px' }}>
      <ReactMarkdown
        children={docmentContent}
        components={Code}
      />
    </div>
  )
}
export default DemoPage

页面效果:
在这里插入图片描述

支持 HTML

修改 MdPreview.js 文件:

import React, { useEffect, useState } from "react"
import ReactMarkdown from 'react-markdown'

import rehypeRaw from 'rehype-raw';

const DemoPage = () => {
  const [docmentContent, setDocmentContent] = useState('')
  
  const content = `<div class="note">Some *emphasis* and <strong>strong</strong>!</div>`
  
  useEffect(() => {
    setDocmentContent(content)
  }, [])
  return (
    <div className="markdown-body" style={{ padding: '30px', borderRadius: '10px' }}>
      <ReactMarkdown children={docmentContent}
        rehypePlugins={[rehypeRaw]} />
    </div>
  )
}
export default DemoPage

页面效果:
在这里插入图片描述

rehype-katexremark-math 展示数学公式

使用 rehype-katexremark-math 可以轻松的翻译输入的数学公式。

注意:需要使用 katex.css 来展示相应的效果,否则会出现公式乱掉的 BUG

index.html 中引入公式解析样式文件:

<!-- 解析Markdown数学公式样式 -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.13/dist/katex.min.css" integrity="sha384-RZU/ijkSsFbcmivfdRBQDtwuwVqK7GMOw6IMvKyeWL2K5UAlyp6WonmB8m7Jd0Hn" crossorigin="anonymous">

修改 MdPreview.js 文件:

import React, { useEffect, useState } from "react"
import ReactMarkdown from 'react-markdown'

import remarkMath from 'remark-math'
import rehypeKatex from 'rehype-katex'

const DemoPage = () => {
  const [docmentContent, setDocmentContent] = useState('')
  const ctx = `$$
  I = \int_0^{2\pi} \sin(x)\,dx
  $$`
  useEffect(() => {
    setDocmentContent(ctx)
  }, [])
  return (
    <div className="markdown-body" style={{ padding: '30px', borderRadius: '10px' }}>
      <ReactMarkdown
        children={docmentContent}
        remarkPlugins={[remarkMath]}
        rehypePlugins={[rehypeKatex]}
      />
    </div>
  )
}
export default DemoPage

页面效果:
在这里插入图片描述

相关链接

react-markdown github 源码
for-editor github
markdown-navbar github

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React markdown 编辑器 的相关文章

  • ubuntu16.04查看硬盘分区使用情况

    方法一 xff1a xff08 推荐 xff09 1 左上角的dash菜单 xff0c 搜索 gnome system monitor 打开磁盘工具 2 在 文件系统 中可以列出已经挂载打开的分区的使用情况 方法二 xff1a 1 左上角的
  • 【ORB-SLAM2】(三):单目摄像头+ROS+ORB_SLAM2实时测试

    介绍 xff1a 首先启动一个单目摄像头 xff0c 其次发布节点话题 usb cam image raw xff0c 最后ORB SLAM2订阅摄像头数据进行处理 xff08 这里需要修改相应的源文件里的话题类型 xff0c 其默认值为
  • vscode如何更换主题

    1 打开Vscode xff0c 点击 文件 首选项 颜色主题 快捷键 xff1a 先按Ctrl 43 K 再按Ctrl 43 T 2 打开主题设置面板 xff0c 在深色主题中点击 深色 3 这样就可以把主题改为 深色 这样Vscode界
  • CSDN写博客更改代码颜色为白色代码样式

    一 背景 在平时发博客时 xff0c 代码块背景默认是黑色的 xff0c 而注释是黑色的 xff0c 总是看起来很不清楚 直接上图 xff1a 注释看起来很不清晰 xff0c 现在我们修改一下颜色为白色 直接上图 xff1a 下面是具体设置
  • win10安装Ubuntu16.04双系统

    下载Ubuntu16 04 xff1a 下载地址 xff1a 官网 xff1a Ubuntu 16 04 7 LTS Xenial Xerus 阿里云开源镜像站 ubuntu releases 16 04安装包下载 开源镜像站 阿里云 中科
  • SLAM后端--滤波方法和非线性优化方法

    SLAM的后端一般分为两种处理方法 xff0c 一种是以扩展卡尔曼滤波 xff08 EKF xff09 为代表的滤波方法 xff0c 一种是以图优化为代表的非线性优化方法 不过 xff0c 目前SLAM研究的主流热点几乎都是基于图优化的 滤
  • React 组件 API

    常用 React 组件 API xff1a 设置状态 xff1a setState替换状态 xff1a replaceState设置属性 xff1a setProps替换属性 xff1a replaceProps强制更新 xff1a for
  • 浅析SATA Physical Layer物理层OOB信号

    一 SATA物理层概述 说OOB之前 xff0c 首先得了解一下SATA结构以及物理层的含义 SATA主要包括 xff1a 应用层 Application Layer 传输层 Transport Layer xff0c 链路层 Link L
  • CodeBlocks 20.03下载及安装指南 使用自带MinGW进行环境配置

    原本用的好好的CodeBlocks 17 12 xff0c 今天手欠无聊去搜了一下官网发现两年都没更新的cb竟然在这两天更新了 对于一直喜欢用最新版的我 xff0c 一定要更新 xff0c 然后 我还把之前的各项配置都删掉了 好吧 xff0
  • 程序是从main主函数开始运行吗?

    很多人开始学计算机语言 xff0c 编写代码时都会有一个疑问 xff1a 程序真的是从main主函数开始的吗 xff1f 之前什么都不做吗 xff1f main结束后就不能执行其他函数了吗 xff1f 下面本篇文章就为此问题做一个简单的解释
  • C++内存越界(转)

    glibc detected free invalid pointer glibc detected malloc memory corruption glibc detected double free or corruption out
  • 总结几种结构体初始化的方法(转)

    总结几种结构体初始化的方法 转自 xff1a http www cnblogs com vongang archive 2011 07 30 2122076 html 结构体能自由组装数据 xff0c 是一种很常见的数据打包方法 当我们定义
  • C++各大有名库的介绍(转)

    C 43 43 各大有名库的介绍 C 43 43 各大有名库的介绍之C 43 43 标准库 标准库中提供了C 43 43 程序的基本设施 虽然C 43 43 标准库随着C 43 43 标准折腾了许多年 xff0c 直到标准的出台才正式定型
  • 内存分配——静态存储区 栈 堆 与static变量 (转)

    一 内存基本构成 可编程内存在基本上分为这样的几大部分 xff1a 静态存储区 堆区和栈区 他们的功能不同 xff0c 对他们使用方式也就不同 静态存储区 xff1a 内存在程序编译的时候就已经分配好 xff0c 这块内存在程序的整个运行期
  • Java的集合框架最全详解(图)

    Java的集合框架最全详解 xff08 图 xff09 前言 xff1a 数据结构对程序设计有着深远的影响 xff0c 在面向过程的C 语言中 xff0c 数据库结构用struct来描述 xff0c 而在面向对象的编程中 xff0c 数据结
  • 如何查看sybase存储过程的内容?

    如何查看sybase存储过程的内容 xff1f 1 在isql xff08 或SQL Advantage xff09 中执行 xff1a sp helptext 存储过程名 可以查看存储过程的内容 2 在 SQL CENTRAL里连接你的服
  • Oracle的表分析是做什么的?

    Oracle的表分析是做什么的 xff1f analyze table tablename compute statistics 分析的结果被Oracle用于基于成本的优化生成更好的查询计划 那么 xff0c 问题在于 xff1a Orac
  • React Refs

    React 支持一种非常特殊的属性 Ref xff0c 可以用来绑定到 render 输出的任何组件上 这个特殊的属性允许引用 render 返回的相应的支撑实例 xff08 backing instance xff09 这样就可以确保在任
  • μC/OS-II学习之:任务,信号量、邮箱、队列及其区别

    一 xff1a UCOS是一种抢占式的多任务操作系统 xff0c 如果最高优先级的任务不主动放弃CPU的使用的话 xff0c 其他任务是无法运行的 xff0c 通常情况下 xff0c 高优先级的任务在使用完CPU或其他资源后都要主动放弃 x
  • 51 单片机简单的多任务调度例子(转)

    51 单片机简单的多任务调度例子 看大家都在学操作系统 xff0c 我也想学学 所以想用51写一个来玩玩 xff0c 发现比较郁闷 弄了几下 xff0c 不想再弄了 xff0c 51弄这个没啥意思 我用的89S52 xff0c 除了速度慢

随机推荐

  • java代码编写随笔总结

    一 项目模块定义 说明 xff1a 一个产品分为各个独立的原子服务 xff0c 通过这些独立的原子服务进行组合来满足各种业务的需求 1 各原子服务关系与原则 xff1a 依赖关系 xff1a 只能上级依赖下级 xff0c 不可下级依赖上级
  • 缓冲区溢出原理学习

    什么是缓冲区溢出 xff1f 缓冲区 简单说来是一块连续的计算机内存区域 可以保存相同数据类型的多个实例 动态变量在程序运行时定位于堆栈之中 我们这里只关心动态缓冲区的溢出问题 即基于堆栈的缓冲区溢出 进程的内存组织形式 一个进程在内存中被
  • Java学习笔记12:求s=1+11+111+1111+......+1111......1的值

    64 author 朱凌风 64 weather 阵雨 64 date 06 19 2011 64 function 计算1 43 11 43 111 43 43 111 1的值 package com jerome import java
  • 配置Ubuntu软件源

    引子 Ubuntu系统的软件源就是指Ubuntu系统的软件更新管理器下载更新软件的来源 xff0c 是一个软件仓库 Ubuntu系统对这个软件源的配置的信息是放在一个文本文件中的 xff0c 这个文本文件的完整路径一般是 etc apt s
  • NuttX 启动流程

    xff08 嵌入式 实时操作系统 rtos nuttx 7 1 stm32 源代码分析 xff09 NuttX 启动流程 转载请注明出处 xff1a http blog csdn net zhumaill article details 2
  • NuttX 介绍

    xff08 嵌入式 实时操作系统 rtos nuttx 7 1 xff09 NuttX 介绍 转载请注明出处 xff1a http blog csdn net zhumaill article details 24197637 1 Nutt
  • Ubuntu用命令行打开网页的三种方法

    1 第一种方法 links命令 apt install links links websol cn 2 第二种方法 w3m命令 apt install w3m w3m websol cn 3 第三种方法 lynx命令 apt install
  • JS删除数组中指定元素/删除数组中指定对象

    删除数组中指定对象指定元素 let arr 61 name 34 xiaowang 34 id 1 name 34 xiaozhang 34 id 2 createDate 34 xiaoli 34 id 3 删除id为1的对象 xff0c
  • React G2Plot 水波图

    官方文档 xff1a https antv g2plot v1 gitee io zh docs manual introduction 安装依赖 span class token function npm span span class
  • 数据链路层

    本篇目录 数据链路层的三个基本问题 使用点对点信道的数据链路层 使用广播信道的数据链路层 以太网MAC层的硬件地址 一 数据链路层的三个基本问题 封装成帧 xff1a 帧是数据链路层的传送单位 一个帧的帧长等于帧的数据部分加上帧的首部和尾部
  • 输入三个数求出最大值(5种方法)

    这是一个很简单的C语言程序 xff0c 重要的是考验思考问题的角度 xff1a 方法1 xff1a include lt stdio h gt void main int a b c scanf 34 d d d 34 amp a amp
  • 把二维数组数据读入txt文本(C语言)

    我们经常需要把计算后的数据存入txt文本 xff0c 下例提供了一种简单思路 xff1a include lt stdio h gt include lt stdlib h gt int main int a 2 3 61 5 2 8 4
  • 查询txt文本信息行数(C和C++分别实现)

    在一些程序设计中 xff0c 我们经常要先查询txt文本的行数 xff0c 据此 xff0c 才能对数组进行动态内存分配 C语言实现 include lt stdio h gt include lt stdlib h gt define A
  • 从txt中读取数据存入二维数组

    在实际应用中 xff0c 经常需要把txt中的数据读入到一个数组中 xff0c 然后再参与运算 在C语言中可以利用fscanf 函数从文件中读取数据 xff0c 示例如下 xff1a void main xff08 xff09 double
  • 仿射变换

    AffineTransform类描述了一种二维仿射变换的功能 xff0c 它是一种二维坐标到二维坐标之间的线性变换 xff0c 保持二维图形的 平直性 xff08 译注 xff1a straightness xff0c 即变换后直线还是直线
  • OpenCV下的直线拟合

    出处 xff1a http blog csdn net Tangyongkang OpenCV中 CvSeq 对象由以下语句生成 创建 CvSeq的容器对象 CvMemStorage storage 61 cvCreateMemStorag
  • 利用meshgrid函数绘制二维高斯函数曲面

    meshgrid函数用于根据给定的横纵坐标点生成坐标网格 xff0c 以便计算二元函数的取值 设二维高斯函数表达式为 xff1a 程序如下 xff1a u 61 10 0 1 10 v 61 10 0 1 10 U V 61 meshgri
  • 要想成功必备的9大好习惯 以及必须克服的9个坏习惯

    要想成功 必备 9 大好习惯 以及 必须克服的 9 个坏习惯 你想成功吗 xff1f 那就及早培养有利于成功的好习惯 习惯的力量是惊人的 xff0c 35岁以前养成的习惯决定着你是否成功 有这样一个寓言故事 一位没有继承人的富豪死后将自己的
  • 数据结构算法学习之路

    1 二分法竞猜商品价格 include lt stdio h gt include lt stdlib h gt int main int oldprice price 61 0 i 61 0 printf 34 请设置商品的真实价格 xf
  • React markdown 编辑器

    react markdown 是一款 github 上开源的适用于 react 的 markdown 组件 xff0c 可以基本实现 markdown 的功能 xff0c 且可以根据自己实际应用定制的 remark 组件 安装 安装 mar