React markdown 编辑器

news2024/11/13 9:54:51

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/462912.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flask+mysql简单问答网站(实现公网可访问)

先到github下载仓库文件 https://github.com/QHCV/flask_mysql_blog python版本3.8&#xff0c;提前安装好Mysql数据库 1.安装python包 pip install -r requirements.txt2.修改配置文件config.py Mysql数据库用户名和密码用于发送验证码的邮箱配置 ​ 在设置->账户下开…

数仓建设规划核心问题!

小A进入一家网约车出现服务公司&#xff0c;负责公司数仓建设&#xff0c;试用期主要一项 OKR是制定数据仓库建设规划&#xff1b;因此小 A 本着从问题出发为原点&#xff0c;先对公司数仓现状进行一轮深入了解&#xff0c;理清存在问题&#xff0c;然后在以不忘初心原则提出解…

提取文本的摘要snownlp模块

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 提取文本的摘要 snownlp模块 [太阳]选择题 关于以下python代码说法错误的一项是&#xff1f; from snownlp import SnowNLP myText """ChatGPT的出现标志着人类科技发…

CSS3 grid网格布局

文章目录 CSS3 grid网格布局概述grid属性说明使用grid-template-rows & grid-template-columns 定义行高和列宽grid-auto-flow 定义项目的排列顺序grid-auto-rows & grid-auto-columns 定义多余网格的行高和列宽row-gap & column-gap 设置行间距和列间距gap 简写形…

Java版spring cloud 本工程项目管理系统源码-全面的工程项目管理

​ ​工程项目管理系统是指从事工程项目管理的企业&#xff08;以下简称工程项目管理企业&#xff09;受业主委托&#xff0c;按照合同约定&#xff0c;代表业主对工程项目的组织实施进行全过程或若干阶段的管理和服务。 如今建筑行业竞争激烈&#xff0c;内卷严重&#xff0c…

Leetcode605. 种花问题

Every day a leetcode 题目来源&#xff1a;605. 种花问题 解法1&#xff1a;贪心 贪心思想&#xff1a;在不打破种植规则的情况下种入尽可能多的花&#xff0c;然后用“最大种植数量”和“所需要种植数量”进行大小比较即可。 设地块长度为n&#xff0c;种花的情况可分为4…

分享一个菜单标签页动画,切换丝滑无比

先上效果图: 代码如下,复制粘贴大法拿走即可使用: <!DOCTYPE html> <html lang="en"> <head>

win系统使用frp端口映射实现内网穿透,配置“任务计划程序”提高稳定性

Github下载最新版frp: https://github.com/fatedier/frp/releases/download/v0.48.0/frp_0.48.0_windows_amd64.zip 解压把frpc.exe和frpc.ini放到D:\program\frp目录下&#xff0c;修改frpc.ini内容如下&#xff1a; [common] server_addr 服务器域名或IP&#xff0c;假设…

Dockerfile镜像LNMP的实战

Dockerfile镜像LNMP的实战 环境准备关闭防火墙拉取centos:7镜像自定义网络 部署nginx&#xff08;容器IP 为 172.18.0.10&#xff09;部署mysql&#xff08;容器IP 为 172.18.0.20&#xff09;部署php&#xff08;容器IP 为 172.18.0.30&#xff09; 环境准备 关闭防火墙 [ro…

taro之项目初始化模板

项目初始化模板 一直以来&#xff0c;在使用 Taro CLI 的 taro init 命令创建项目时&#xff0c;CLI 会提供若干内置模板给开发者选择。但是很多团队都有自己独特的业务场景&#xff0c;需要使用和维护的模板也不尽一致&#xff0c;因此 Taro 支持把项目模板打包成一个能力赋予…

JavaScript奇技淫巧:debugger拦截

debugger指令&#xff0c;一般用于调试&#xff0c;在如浏览器调试执行环境中&#xff0c;可以在JavaScript代码中产生中断。 如果想要拦截debugger&#xff0c;是不容易的&#xff0c;常用的函数替代、proxy方法均对它无效&#xff0c;如&#xff1a; window.debugger (fun…

电脑音乐相册软件推荐 电脑音乐相册制作方法

音乐相册就是把照片剪辑成视频&#xff0c;并配上动听的音乐。音乐相册很适合保存照片&#xff0c;记录生活&#xff0c;传达出拍摄者当时的心情。下面为大家带来电脑音乐相册软件推荐&#xff0c;电脑音乐相册制作方法。 一、电脑音乐相册软件推荐 很多小伙伴在制作音乐相册…

大数据Doris(三):Apache Doris分布式部署准备工作

文章目录 Apache Doris分布式部署准备工作 一、Apache Doris下载 二、节点划分 三、节点配置 1、设置文件句柄数 2、时间同步 3、关闭 Swap 分区 4、调大单个进程的虚拟内存区域数量 Apache Doris分布式部署准备工作 部署Apache Doris时需要分别部署FE、BE、Broker。然…

iOS - RunLoop 基本原理介绍

一、Runloop 简介 Runloop 是通过内部维护事件循环来对事件/消息进行管理的一个对象。 事件循环&#xff08;状态切换&#xff09; 没有消息需要处理时&#xff0c;休眠以避免资源占用&#xff08;用户态 -> 内核态&#xff09;有消息需要处理时&#xff0c;立刻被唤醒&a…

电视盒子什么牌子好?数码博主盘点2022电视盒子排行榜

网络电视盒子是电视机的标配&#xff0c;开放性的安卓系统能观看海量视频资源&#xff0c;我每年也会进行电视盒子的测评&#xff0c;今天要来分享五款最热门的网络电视盒子推荐&#xff0c;跟着我一起看看网络电视盒子哪个好。 一&#xff1a;泰捷WEBOX60Pro电视盒子 年度…

【华为HCIP | 高级网络工程师】刷题日记(1)

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大二在校生&#xff0c;讨厌编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;落. &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️ 零基础…

03-stable diffusion国风小姐姐

stable diffusion 文生图 – 生成国风小姐姐 一、模型在哪里下载 下载网站civitai&#xff1a; Civitai | Stable Diffusion models, embeddings, LoRAs and more国风主模型&#xff1a;https://civitai.com/models/14171/cutegirlmix4主模型放到sd-webui-aki-v4\models\Stab…

【AUTOSAR】【信息安全】CSM

目录 一、概述 二、依赖模块 三、功能描述 3.1 基本体系结构 3.2 通用行为 3.2.1 正常操作 3.2.2 设计说明 3.3 错误分类 3.3.1 开发错误 3.3.2 运行时错误 四、API接口 4.1 通用接口 4.2 加密接口 4.3 秘钥接口 4.4 Job接口 4.5 回调接口 4.6 调度接口 一、概…

配置中心基本原理

配置中心是如何实现推送的&#xff1f; 背景 传统的静态配置方式想要修改某个配置时&#xff0c;必须重新启动一次应用&#xff0c;如果是数据库连接串的变更&#xff0c;那可能还容易接受一些&#xff0c;但如果变更的是一些运行时实时感知的配置&#xff0c;如某个功能项的…

ROS学习第四十一节——SLAM建图

https://download.csdn.net/download/qq_45685327/87721374 准备工作 请先安装相关的ROS功能包: 安装 gmapping 包(用于构建地图):sudo apt install ros-melodic-gmapping 安装地图服务包(用于保存与读取地图):sudo apt install ros-melodic-map-server 安装 navigation 包…