8

XK-Editor - 一个支持富文本和Markdown的编辑器

 1 year ago
source link: https://blog.ixk.me/post/xkeditor
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
本文最后更新于 268 天前,文中所描述的信息可能已发生改变

这个项目原本是为了升级 XK-Note 而创造的,后来因为功能的不断完善,逐渐的改成了可复用的组件。XK-Note 原本是使用 Editor.md 的编辑器,使用起来也很不错,但是总有一些不如意的地方,于是便打算自己造个编辑器。

XK-Editor 基于 Vue 是因为双向绑定这个特性,同时也是模板语法,便于开发,之所以采用 ACE 编辑器其实是当时觉得 CodeMirror 太丑了,实际开发中 ACE 实在太难弄了,文档跟不存在一样,只能阅读源码来实现一些不常见的功能,同时也修补了 Editor.md 中一些不如意的地方,比如没有打字机模式,每次写到屏幕下方的时候总是要重新滚动,代码高亮不够漂亮,没有自动补全等等。。。又引入了 Tiny MCE 使得编辑器拥有了富文本编辑的功能。

简介 Introduction

XK-Editor=Vue2.0+Ace+TinyMCE;

XK-Editor 支持富文本编辑和 Markdown ,同时可以在 Markdown 和 HTML 互转,满足各种人的需求。

特性 Feature

  • [两种编辑器] 支持富文本编辑和 Markdown 编辑
  • [两种格式互转] 支持 Markdown 和 HTML 互转
  • [打字机模式] 支持打字机模式,编辑时无需使用鼠标滚轮,并可调节定位位置,满足各种屏幕和使用者的需求
  • [粘贴自动格式化] 支持在粘贴 HTML 时自动将 HTML 格式化为 Markdown
  • [图片粘贴自动上传] 支持粘贴图片自动上传,并自动填充链接
  • [嵌入运行块] 支持嵌入可运行的代码块,通过与后端交互可以支持多种语言
  • [下载] 支持导出下载 Markdown 和 HTML 格式的文件
  • [即时保存] 支持即时保存到浏览器,无惧网络波动
  • [移动端优化] 优化移动端的编辑体验,支持惯性滚动,并默认关闭实时预览
  • [滚动绑定] 支持双向/单向滚动绑定,使预览能够跟随输入
  • [树形 TOC] 目录可折叠,不用再翻阅很久来定位
  • [自定义主题] 支持自定义主题,可以通过替换 CSS 来更换显示样式
  • [Emoji 表情] 支持 Github 语法的表情 :smile:
  • [Task lists] 支持创建 Task 列表
  • [TeX 公式] 支持插入 KaTex 公式
  • [流程图/时序图/甘特图] 支持 mermaid 语法编写各种图
  • [解析 HTML] 支持解析各种 HTML 标签,并支持过滤标签
  • [独有的扩展语法] 拥有一些扩展语法
  • [自动补全] 支持语法自动补全
  • [图片上传] 支持图片上传
  • 还有多种神奇的功能等待你的发掘。

演示 Demo

XK-Editor

安装 Install

XK-Editor 还在不断的改进中 API 可能会更改

从 Version 1.0.8 开始,为了减小 Vendor 体积,防止加载时间过长,XK-Editor 默认使用 jsDelivr CDN 加载部分 node_modules 需要在 index.html 中添加以下 script 标签,若您不打算使用该方式加载,请将 node_modules/xkeditor/components 下的文件中所有的 import 注释取消。

从 Version 1.4.6 开始,模块默认通过 webpack externals 方式导入,所以您需要修改 webpack 的配置文件,添加对应的配置,如下

1<!-- ACE Editor -->
2<script src="https://cdn.jsdelivr.net/npm/[email protected]/src-noconflict/ace.min.js"></script>
3<script src="https://cdn.jsdelivr.net/npm/[email protected]/src-noconflict/ext-language_tools.js"></script>
4<!-- Marked -->
5<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/marked.min.js"></script>
6<!-- Turndown -->
7<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/turndown.min.js"></script>
8<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/turndown-plugin-gfm.min.js"></script>
9<!-- Preitter -->
10<script src="https://cdn.jsdelivr.net/npm/[email protected]/standalone.js"></script>
11<script src="https://cdn.jsdelivr.net/npm/[email protected]/parser-markdown.js"></script>
12<!-- Prism.js -->
13<script src="/static/prism.js"></script>
14<link rel="stylesheet" href="/static/prism-okaidia.css" />
15<link rel="stylesheet" href="/static/prism-line-numbers.css" />
16<link rel="stylesheet" href="/static/prism-toolbar.css" />
17<!-- Katex -->
18<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js"></script>
19<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js"></script>
20<link
21  rel="stylesheet"
22  href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css"
23/>
24<!-- Mermaid -->
25<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/mermaid.min.js"></script>
26<!-- Emoji-js -->
27<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/emoji.min.js"></script>
28<!-- TinyMCE -->
29<script src="https://cdn.jsdelivr.net/npm/[email protected]/tinymce.min.js"></script>
30<script src="https://cdn.jsdelivr.net/npm/[email protected]/themes/silver/theme.min.js"></script>
31<script src="https://cdn.jsdelivr.net/combine/npm/[email protected]/plugins/print/plugin.min.js,npm/[email protected]/plugins/preview/plugin.min.js,npm/[email protected]/plugins/fullpage/plugin.min.js,npm/[email protected]/plugins/fullscreen/plugin.min.js,npm/[email protected]/plugins/searchreplace/plugin.min.js,npm/[email protected]/plugins/autolink/plugin.min.js,npm/[email protected]/plugins/directionality/plugin.min.js,npm/[email protected]/plugins/code/plugin.min.js,npm/[email protected]/plugins/visualblocks/plugin.min.js,npm/[email protected]/plugins/visualchars/plugin.min.js,npm/[email protected]/plugins/image/plugin.min.js,npm/[email protected]/plugins/link/plugin.min.js,npm/[email protected]/plugins/media/plugin.min.js,npm/[email protected]/plugins/template/plugin.min.js,npm/[email protected]/plugins/codesample/plugin.min.js,npm/[email protected]/plugins/table/plugin.min.js,npm/[email protected]/plugins/charmap/plugin.min.js,npm/[email protected]/plugins/hr/plugin.min.js,npm/[email protected]/plugins/pagebreak/plugin.min.js,npm/[email protected]/plugins/nonbreaking/plugin.min.js,npm/[email protected]/plugins/anchor/plugin.min.js,npm/[email protected]/plugins/toc/plugin.min.js,npm/[email protected]/plugins/insertdatetime/plugin.min.js,npm/[email protected]/plugins/advlist/plugin.min.js,npm/[email protected]/plugins/lists/plugin.min.js,npm/[email protected]/plugins/wordcount/plugin.min.js,npm/[email protected]/plugins/imagetools/plugin.min.js,npm/[email protected]/plugins/textpattern/plugin.min.js"></script>
1module.exports = {
2  externals: {
3    "ace-builds": "ace",
4    marked: "marked",
5    turndown: "TurndownService",
6    "turndown-plugin-gfm": "turndownPluginGfm",
7    prismjs: "Prism",
8    "emoji-js": "EmojiConvertor",
9    "tinymce/tinymce": "tinyMCE",
10    mermaid: "mermaid",
11    katex: "katex",
12    "katex/dist/contrib/auto-render": "renderMathInElement"
13  }
14};

从 NPM 安装

你可以轻松将 XK-Editor 引入你现有的项目

  • 安装 XK-Editor
1npm i --save xkeditor
  • 将 XK-Editor static 文件复制到项目根目录
1cp -r ./node_modules/xkeditor/public/static ./
  • 导入 XK-Editor 组件
1import XK_Editor from "xkeditor";
2export default {
3  components: {
4    "xk-editor": XK_Editor
5  }
6};
  • 使用 XK-Editor 组件
1<xk-editor :config="config" v-model="content" :data.sync="data" />
2<!-- config(Object) 是下方 config 内容,该参数是单向的,Editor 内部的设置变动不会同步到父组件 -->
3<!-- v-model(String) 对应 Markdown 内容,该参数是双向的,由于 ACE 和 TinyMCE 编辑器的限制,当该参数被外部修改的时候,即与内部 Markdown 内容不一致时,会触发 ACE 编辑器和 TinyMCE 的 setValue,此时光标将会重置。 -->
4<!-- data(Object) 是 XK-Editor 扩展的数据内容,用来存储一些非 Markdown 的数据,该参数是双向的 -->
1ace-builds
2@fortawesome/fontawesome-svg-core
3@fortawesome/free-solid-svg-icons
4@fortawesome/vue-fontawesome
5@tinymce/tinymce-vue
6axios
7emoji-js
8katex
9marked
10mermaid
11prismjs
12tinymce
13turndown
14turndown-plugin-gfm

config && data

1var config = {
2  // 该设置为 TinyMCE 的设置,详情见 TinyMCE 编辑器的文档
3  tinymceSetting: {
4    language_url: "/static/tinymce/langs/zh_CN.js",
5    language: "zh_CN",
6    skin_url: "/static/tinymce/skins/ui/oxide",
7    body_class: "markdown-body",
8    content_css: "/static/github-markdown.css",
9    plugins:
10      "print preview fullpage searchreplace autolink directionality code visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists wordcount imagetools textpattern",
11    toolbar:
12      "formatselect | fontsizeselect | bold italic underline strikethrough blockquote forecolor backcolor prismjs | link image media pageembed | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | tex-$ tex-math flow seq gantt mermaid | removeformat code toMarkdownEditor | undo redo",
13    image_advtab: true,
14    importcss_append: true,
15    height: "100%",
16    template_cdate_format: "[CDATE: %m/%d/%Y : %H:%M:%S]",
17    template_mdate_format: "[MDATE: %m/%d/%Y : %H:%M:%S]",
18    image_caption: true,
19    spellchecker_dialog: true,
20    spellchecker_whitelist: ["Ephox", "Moxiecode"]
21  },
22  // 该设置为 ACE 编辑器的设置,详情见 ACE 编辑器文档
23  aceSetting: {
24    // toolbar 为 XK-Editor 扩展的字段,语法和 tinymce 的 toolbar 字段一致
25    toolbar:
26      "h1 h2 h3 h4 h5 h6 | bold italic underline strikethrough quote mark code | sup sub tex-$ tex-math | flow seq gantt mermaid | ul ol minus table time | link image video graff | toLine search toc typewriter switchPreview fullPreview fullScreen toHtmlEditor toTinyMCE format empty setting | undo redo | setLocalStorage getLocalStorage removeLocalStorage | help info | pasteFormat",
27    minLines: 10,
28    fontSize: "17px",
29    theme: "ace/theme/solarized_light",
30    mode: "ace/mode/markdown",
31    tabSize: 4,
32    wrap: true,
33    enableSnippets: true,
34    enableLiveAutocompletion: true,
35    enableBasicAutocompletion: true,
36    value: "# XK-Editor"
37  },
38  // XK-Editor 相关设置
39  xkSetting: {
40    // 暂时无用
41    apiBaseUrl: "",
42    // 预览的 CSS 文件,类似于主题
43    previewCss: "/static/github-markdown.css",
44    // 预览的 class
45    previewClass: "markdown-body",
46    // 延迟渲染时间 (ms),由于性能因素 XK-Editor 限制该选项不能低于 500ms
47    delayToHtml: 500,
48    // 滚动绑定,(left,right,both)
49    scrollBind: "both",
50    // 图片上传的地址
51    imgUpload: "http://example.com/upload.php",
52    // 滚动模式,默认使用 JavaScript 的方式来滚动,防止与 Hash Router 冲突
53    scrollMode: "javascript",
54    // 粘贴格式化
55    pasteFormat: true,
56    // 粘贴自动上传(仅对复制图像时有效,混合内容无效,需要设置图片上传地址)
57    pasteImageUpload: true,
58    // 是否开启 TinyMCE 编辑器
59    enableTinyMCE: true,
60    // run-code 的地址
61    judge0API: "https://example.com",
62    // run-code 语言列表
63    runCodeLangList: {
64      c: 1,
65      cpp: 2,
66      bash: 3,
67      csharp: 4,
68      go: 5,
69      java: 6,
70      node: 7,
71      php: 8,
72      python: 9,
73      python2: 10,
74      ruby: 11,
75      rust: 12,
76      scala: 13,
77      typescript: 14
78    }
79  }
80};
81var data = {
82  graff: {
83    // SVG Hash
84    "6b3117":
85      // viewBox|SVG innerHTML
86      '8.399999618530273 9 423.9984436035156 154|<path d="M 290.4,100 L 293.4,104 L 304.4,112 L 326.4,123 L 345.4,131 L 360.4,136 L 378.4,140 L 395.4,145 L 405.4,148 L 415.4,152 L 420.4,152 L 421.4,153 L 422.4,153" fill="none" stroke="#6190e8" stroke-width="2"></path><rect x="18.4" y="19" fill="none" stroke="#6190e8" stroke-width="2" width="131" height="69" d="M 18.4 19 h 131 v 69 h -131 Z"></rect>'
87  }
88};

运行代码块

运行代码块除 javascript 不需要使用后端,其他语言都需要有后端负责执行代码。 后端执行器基于 judge0/api 重新 build 而来,支持的语言详见 run-code,若您有其他语言的需求,您可以自行参照教程重新 build

run-code

文档 Doc

Wiki

Github

求 star = ̄ ω  ̄=

维护者 Maintainer

XK-Editor 由 Otstar Lin 和下列 贡献者 的帮助下撰写和维护。

Otstar Lin -Personal Website·Blog·Github

许可证 License

根据 Apache License 2.0 许可证开源。

渲染 Render

8d1b3502 a349 4999 ac92 d0db53583c70
28907719 a1f2 42fc 8bd6 b46459d48ebe

首先感谢你能看到最后,同时感谢你对该项目的兴趣。 该项目虽然不大,大部分核心的部件也是使用现成的组件,但是对我来说也是一次良好的经验,也是我第一个完整的前端项目,所以难免会有 Bug,若您在使用遇到了问题,请及时联系我进行修复,或者到 Github 上提交 issue,我会尽快的处理,另外若您有其他好的建议或者有希望增加的功能,请联系我进行添加或者提交 Pull Request。

Coding 最大的乐趣,不在 Coding,而在 Creating。 --- Otstar Lin


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK