当前位置:网站首页>一款开源的Markdown转富文本编辑器的实现原理剖析
一款开源的Markdown转富文本编辑器的实现原理剖析
2022-07-03 09:01:00 【科技那些事儿】
笔者平时写文章使用的都是Markdown,但是发布的时候就会遇到一些平台不支持Markdown的情况,重排是不可能重排的,所以都会使用一些Markdown转富文本的工具,比如markdown-nice,用的多了就会好奇是怎么实现的,于是就有了本篇文章。
markdown-nice是一个基于React构建的项目,先来看一下它的整体页面:

一个顶部工具栏,中间三个并列的区域,分别是编辑区域、预览区域、自定义主题区域,自定义主题区域默认是隐藏的。
大体上就是一个Markdown编辑器,增加了一些对各个平台的适配而已。
编辑器
编辑器使用的是CodeMirror,具体来说是一个二次封装的组件React-CodeMirror:
import CodeMirror from "@uiw/react-codemirror";
class App extends Component {
render() {
return (
<CodeMirror
value={this.props.content.content}
options={
{
theme: "md-mirror",// 主题
keyMap: "sublime",// 快捷键
mode: "markdown",// 模式,也就是语言类型
lineWrapping: true,// 开启超长换行
lineNumbers: false,// 不显示行号
extraKeys: {// 配置快捷键
...bindHotkeys(this.props.content, this.props.dialog),
Tab: betterTab,
RightClick: rightClick,
},
}}
onChange={this.handleThrottleChange}
onScroll={this.handleScroll}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
onDrop={this.handleDrop}
onPaste={this.handlePaste}
ref={this.getInstance}
/>
)
}
}
复制代码快捷键、命令
markdown-nice通过extraKeys选项设置一些快捷键,此外还在工具栏中增加了一些快捷按钮:

这些快捷键或者命令按钮操作文本内容的逻辑基本是一致的,先获取当前选区的内容:
const selected = editor.getSelection()
复制代码然后进行加工修改:
`**${selected}**`
复制代码最后替换选区的内容:
editor.replaceSelection(`**${selected}**`)
复制代码此外也可以修改光标的位置来提升体验,比如加粗操作后光标位置会在文字后面,而不是*后面就是因为markdown-nice在替换完选区内容后还修改了光标的位置:

export const bold = (editor, selection) => {
editor.replaceSelection(`**${selection}**`);
const cursor = editor.getCursor();
cursor.ch -= 2;// 光标位置向前两个字符
editor.setCursor(cursor);
};
复制代码表格
Markdown的表格语法手写起来是比较麻烦的,markdown-nice对于表格只提供了帮你插入表格语法符号的功能,你可以输入要插入的表格行列数:

确认以后会自动插入符号:

实现其实就是一个字符串的拼接逻辑:
const text = this.buildFormFormat(this.state.rowNum, this.state.columnNum);
buildFormFormat = (rowNum, columnNum) => {
let formFormat = "";
// 最少会创建三行
for (let i = 0; i < 3; i++) {
formFormat += this.buildRow(i, columnNum);
}
// 超过三行
for (let i = 3; i <= rowNum; i++) {
formFormat += this.buildRow(i, columnNum);
}
return formFormat;
};
buildRow = (rowNum, columnNum) => {
let appendText = "|";
// 第一行为表头和内容的分隔
if (rowNum === 1) {
appendText += " --- |";
for (let i = 0; i < columnNum - 1; i++) {
appendText += " --- |";
}
} else {
appendText += " |";
for (let i = 0; i < columnNum - 1; i++) {
appendText += " |";
}
}
return appendText + (/windows|win32/i.test(navigator.userAgent) ? "\r\n" : "\n");
};
复制代码表格字符生成以后替换当前选区内容即可:
handleOk = () => {
const {markdownEditor} = this.props.content;
const cursor = markdownEditor.getCursor();
const text = this.buildFormFormat(this.state.rowNum, this.state.columnNum);
markdownEditor.replaceSelection(text);
cursor.ch += 2;
markdownEditor.setCursor(cursor);
markdownEditor.focus();
};
复制代码同样修改了光标位置并且让编辑器重新聚焦。
边栏推荐
- Go language - IO project
- [point cloud processing paper crazy reading frontier version 10] - mvtn: multi view transformation network for 3D shape recognition
- Crawler career from scratch (I): crawl the photos of my little sister ① (the website has been disabled)
- Solve POM in idea Comment top line problem in XML file
- 2022-2-14 learning xiangniuke project - Session Management
- Crawler career from scratch (V): detailed explanation of re regular expression
- 【点云处理之论文狂读前沿版9】—Advanced Feature Learning on Point Clouds using Multi-resolution Features and Learni
- MySQL installation and configuration (command line version)
- LeetCode每日一题(2115. Find All Possible Recipes from Given Supplies)
- [untitled] use of cmake
猜你喜欢

CATIA automation object architecture - detailed explanation of application objects (III) systemservice

Computing level network notes
![[kotlin learning] operator overloading and other conventions -- overloading the conventions of arithmetic operators, comparison operators, sets and intervals](/img/8d/938e232c1016cabe9ee0f72be87a22.png)
[kotlin learning] operator overloading and other conventions -- overloading the conventions of arithmetic operators, comparison operators, sets and intervals
![[point cloud processing paper crazy reading classic version 11] - mining point cloud local structures by kernel correlation and graph pooling](/img/40/e0c7bad60b19cafa467c229419ac21.png)
[point cloud processing paper crazy reading classic version 11] - mining point cloud local structures by kernel correlation and graph pooling

Crawler career from scratch (3): crawl the photos of my little sister ③ (the website has been disabled)

2022-1-6 Niuke net brush sword finger offer

【Kotlin学习】类、对象和接口——带非默认构造方法或属性的类、数据类和类委托、object关键字

Redis learning (I)

Hudi learning notes (III) analysis of core concepts
![[set theory] order relation (eight special elements in partial order relation | ① maximum element | ② minimum element | ③ maximum element | ④ minimum element | ⑤ upper bound | ⑥ lower bound | ⑦ minimu](/img/57/b413a93a456a1872fc19aa825c937a.jpg)
[set theory] order relation (eight special elements in partial order relation | ① maximum element | ② minimum element | ③ maximum element | ④ minimum element | ⑤ upper bound | ⑥ lower bound | ⑦ minimu
随机推荐
Tag paste operator (#)
Save the drama shortage, programmers' favorite high-score American drama TOP10
[graduation season | advanced technology Er] another graduation season, I change my career as soon as I graduate, from animal science to programmer. Programmers have something to say in 10 years
[set theory] order relation (chain | anti chain | chain and anti chain example | chain and anti chain theorem | chain and anti chain inference | good order relation)
Hudi学习笔记(三) 核心概念剖析
Install database -linux-5.7
Derivation of Fourier transform
Flink学习笔记(十)Flink容错机制
CATIA automation object architecture - detailed explanation of application objects (III) systemservice
Hudi 快速体验使用(含操作详细步骤及截图)
Common formulas of probability theory
2022-2-14 learning xiangniuke project - Session Management
LeetCode每日一题(931. Minimum Falling Path Sum)
Severity code description the project file line prohibits the display of status error c2440 "initialization": unable to convert from "const char [31]" to "char *"
LeetCode每日一题(985. Sum of Even Numbers After Queries)
MySQL installation and configuration (command line version)
【Kotlin学习】运算符重载及其他约定——重载算术运算符、比较运算符、集合与区间的约定
Go language - Reflection
Go language - JSON processing
307. Range Sum Query - Mutable