当前位置:网站首页>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 .
边栏推荐
- LeetCode每日一题(931. Minimum Falling Path Sum)
- 【Kotlin学习】高阶函数的控制流——lambda的返回语句和匿名函数
- Basic knowledge of database design
- Word segmentation in full-text indexing
- 数字身份验证服务商ADVANCE.AI顺利加入深跨协 推进跨境电商行业可持续性发展
- Jestson Nano自定义根文件系统创建(支持NVIDIA图形库的最小根文件系统)
- LeetCode每日一题(2232. Minimize Result by Adding Parentheses to Expression)
- Long类型的相等判断
- LeetCode每日一题(2115. Find All Possible Recipes from Given Supplies)
- Liteide is easy to use
猜你喜欢

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

Flask+supervisor installation realizes background process resident

Spark overview

Flink学习笔记(九)状态编程

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

数字身份验证服务商ADVANCE.AI顺利加入深跨协 推进跨境电商行业可持续性发展

Redis learning (I)

Nodemcu-esp8266 development (vscode+platformio+arduino framework): Part 2 --blinker_ Hello_ WiFi (lighting technology - Mobile App control routine)

Common software open source protocols

LeetCode每日一题(931. Minimum Falling Path Sum)
随机推荐
PIP configuring domestic sources
一款开源的Markdown转富文本编辑器的实现原理剖析
Crawler career from scratch (V): detailed explanation of re regular expression
Vscode编辑器右键没有Open In Default Browser选项
解决Editor.md上传图片获取不到图片地址问题
Nodemcu-esp8266 development (vscode+platformio+arduino framework): Part 1 -- establishment of engineering template -template
Matlab dichotomy to find the optimal solution
[solution to the new version of Flink without bat startup file]
软件测试工程师是做什么的 通过技术测试软件程序中是否有漏洞
QT sub window is blocked, and the main window cannot be clicked after the sub window pops up
文件系统中的目录与切换操作
Basic knowledge of database design
Learning C language from scratch -- installation and configuration of 01 MinGW
Solve the problem of disordered code in vscode development, output Chinese and open source code
LeetCode每日一题(745. Prefix and Suffix Search)
Please tell me how to set vscode
Apply for domain name binding IP to open port 80 record
LeetCode每日一题(1996. The Number of Weak Characters in the Game)
PolyWorks script development learning notes (I) - script development environment
CATIA automation object architecture - detailed explanation of application objects (I) document/settingcontrollers