笔者平时写文章应用的都是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();
};
复制代码
同样批改了光标地位并且让编辑器从新聚焦。