当前位置:网站首页>Analysis of the implementation principle of an open source markdown to rich text editor
Analysis of the implementation principle of an open source markdown to rich text editor
2022-07-03 09:32:00 【Technology stuff】
I usually write articles using Markdown, However, some platforms do not support it when it is released Markdown The situation of , Rearrangement is impossible , So they all use some Markdown A tool for converting rich text , such as markdown-nice, If you use more, you will be curious about how it is realized , So there's this article .
markdown-nice It's based on React Projects built , Let's take a look at its overall page first :

A Top Toolbar , Three parallel areas in the middle , These are the editing areas 、 The preview area 、 Customize the theme area , The custom theme area is hidden by default .
It's basically a Markdown Editor , Added some adaptations to various platforms .
Editor
The editor uses CodeMirror, Specifically, it is a secondary encapsulated component React-CodeMirror:
import CodeMirror from "@uiw/react-codemirror";
class App extends Component {
render() {
return (
<CodeMirror
value={this.props.content.content}
options={
{
theme: "md-mirror",// The theme
keyMap: "sublime",// Shortcut key
mode: "markdown",// Pattern , That is, the language type
lineWrapping: true,// Turn on extra long line feed
lineNumbers: false,// Don't show line numbers
extraKeys: {// Configure shortcut keys
...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}
/>
)
}
}
Copy code Shortcut key 、 command
markdown-nice adopt extraKeys Option to set some shortcut keys , In addition, some shortcut buttons have been added to the toolbar :

The logic of these shortcut keys or command buttons to operate the text content is basically the same , Get the contents of the current selection first :
const selected = editor.getSelection()
Copy code Then carry out machining modification :
`**${selected}**`
Copy code Finally, replace the contents of the selection :
editor.replaceSelection(`**${selected}**`)
Copy code In addition, you can modify the position of the cursor to improve the experience , For example, the cursor position will be behind the text after the bold operation , instead of * The reason behind this is markdown-nice After replacing the contents of the selected area, the cursor position is also modified :

export const bold = (editor, selection) => {
editor.replaceSelection(`**${selection}**`);
const cursor = editor.getCursor();
cursor.ch -= 2;// Two characters ahead of the cursor position
editor.setCursor(cursor);
};
Copy code form
Markdown The table grammar of is troublesome to write ,markdown-nice For tables, it only provides the function of inserting table syntax symbols for you , You can enter the number of table rows and columns to insert :

The symbol will be automatically inserted after confirmation :

The implementation is actually a string splicing logic :
const text = this.buildFormFormat(this.state.rowNum, this.state.columnNum);
buildFormFormat = (rowNum, columnNum) => {
let formFormat = "";
// At least three rows will be created
for (let i = 0; i < 3; i++) {
formFormat += this.buildRow(i, columnNum);
}
// More than three lines
for (let i = 3; i <= rowNum; i++) {
formFormat += this.buildRow(i, columnNum);
}
return formFormat;
};
buildRow = (rowNum, columnNum) => {
let appendText = "|";
// The first line is the separation of header and content
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");
};
Copy code After the table characters are generated, you can replace the contents of the current selection :
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();
};
Copy code Also changed the cursor position and refocused the editor .
边栏推荐
- [untitled] use of cmake
- Matlab dichotomy to find the optimal solution
- Installation and uninstallation of pyenv
- [point cloud processing paper crazy reading classic version 13] - adaptive graph revolutionary neural networks
- Usage of pandas to obtain MySQL data
- 2022-2-14 learning xiangniuke project - generate verification code
- Install database -linux-5.7
- LeetCode每日一题(2232. Minimize Result by Adding Parentheses to Expression)
- Redis learning (I)
- Numerical analysis notes (I): equation root
猜你喜欢

Crawler career from scratch (3): crawl the photos of my little sister ③ (the website has been disabled)
![[point cloud processing paper crazy reading frontier version 11] - unsupervised point cloud pre training via occlusion completion](/img/76/b92fe4549cacba15c113993a07abb8.png)
[point cloud processing paper crazy reading frontier version 11] - unsupervised point cloud pre training via occlusion completion

Construction of simple database learning environment

【Kotlin学习】类、对象和接口——定义类继承结构

LeetCode每日一题(931. Minimum Falling Path Sum)

LeetCode每日一题(1162. As Far from Land as Possible)

【点云处理之论文狂读前沿版11】—— Unsupervised Point Cloud Pre-training via Occlusion Completion

NPM install installation dependency package error reporting solution

2022-2-14 learning the imitation Niuke project - send email

Solve POM in idea Comment top line problem in XML file
随机推荐
Idea uses the MVN command to package and report an error, which is not available
Flink学习笔记(十一)Table API 和 SQL
Navicat, MySQL export Er graph, er graph
[kotlin puzzle] what happens if you overload an arithmetic operator in the kotlin class and declare the operator as an extension function?
Make the most basic root file system of Jetson nano and mount NFS file system on the server
LeetCode每日一题(516. Longest Palindromic Subsequence)
Apply for domain name binding IP to open port 80 record
2022-2-14 learning the imitation Niuke project - send email
【Kotlin学习】类、对象和接口——带非默认构造方法或属性的类、数据类和类委托、object关键字
Jenkins learning (II) -- setting up Chinese
Utilisation de hudi dans idea
[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)
Quickly use markdown to edit articles
PolyWorks script development learning notes (4) - data import and alignment using file import
Spark 结构化流写入Hudi 实践
Jenkins learning (I) -- Jenkins installation
Logstash+jdbc data synchronization +head display problems
[kotlin learning] operator overloading and other conventions -- overloading the conventions of arithmetic operators, comparison operators, sets and intervals
Hudi学习笔记(三) 核心概念剖析
On February 14, 2022, learn the imitation Niuke project - develop the registration function