程序员|任由文字肆意流淌,更自由的开源 Markdown 编辑器


程序员|任由文字肆意流淌,更自由的开源 Markdown 编辑器
文章图片
程序员|任由文字肆意流淌,更自由的开源 Markdown 编辑器
文章图片
程序员|任由文字肆意流淌,更自由的开源 Markdown 编辑器
文章图片
程序员|任由文字肆意流淌,更自由的开源 Markdown 编辑器
文章图片
程序员|任由文字肆意流淌,更自由的开源 Markdown 编辑器
文章图片
程序员|任由文字肆意流淌,更自由的开源 Markdown 编辑器
文章图片
程序员|任由文字肆意流淌,更自由的开源 Markdown 编辑器
文章图片
对于创作平台来说内容编辑器是十分重要的功能 , 强大的编辑器可以让创作者专注于创作“笔”下生花 。 而最好取悦程序员创作者的方法之一就是支持 Markdown 写作 , 因为大多数程序员都是用 Markdown 来写文章 。
Markdown 作为程序员写作的心头爱 , 有很多优点:

  • 通过语法实现排版 , 不需要点选手动设置样式
  • 快速实现复杂内容 , 如:代码块、超链接、公式等
  • 让创作者有更多时间专注于内容
但 , 同样的也有些缺点:
  • 有一定的学习门槛 , 对于非程序员不太友好
  • 看原文档就像看“代码” , 预览效果需要工具或编辑器支持
那有没有能够即保留 Markdown 带来的便利 , 同时又降低门槛的办法呢?大多数老玩家会脱口而出:Typora
Typora 直接使用完全没有问题 , 但由于它没有开源 。 如果想在自己的项目实现类似的 Markdown 编辑器 , 就需要另寻方案了 。
如果你正在寻找功能强大、易于接入、所见即所得的 Markdown 编辑器、组件、插件 , 就请花 5 分钟读完本文!
接下来 HelloGitHub 带来的开源项目完全满足上述需求 。 Milkdown 一款高颜值+自由(插件)的所见即所得 , 集合 Markdown 编辑器、组件、插件于一身的开源项目 。
你想要的功能它都有 , 不要的功能也可以通过删减插件 , 减少体积 。 插件的设计思想+完善的中文文档 , 让你分分钟定制出最适合自己的 Markdown 编辑器!
下面跟着项目作者一起来感受 Milkdown 的魅力吧 。
一、上手下面提供了 2 种方式 , 可直接体验:
在线尝试、VS Code 插件
1.1 功能展示方便的编写表格:
直接粘贴和复制 Markdown 文本:
甚至协同编辑:
双栏 Markdown 编辑器很常见 。 但双向绑定的 Markdown 编辑器 , 目前仅此一家:
功能方面就介绍这么多 , 下面用 Milkdown 轻松实现个编辑器 。
1.2 第一个编辑器Milkdown 的核心以及各种插件都是独立的 NPM 包 , 可以直接通过 NPM 来进行安装 。
我们先使用make 来初始化编辑器 , 然后使用use 来加载插件 , 最后使用create 来创建编辑器 。
1.3 丰富的插件插件是 Milkdown 的核心 , 它本质上就是一个插件加载器 , 一切功能都是通过插件来提供的 。 表格是一个插件、主题是一个插件、甚至一行简单的文本也是一个插件 。
目前官方已经提供了许多插件 , 确保可以开箱即用 。 下面仅列举了部分插件:
也可以自己动手编写插件 , 更多详情
二、技术栈Milkdown 基于下面的工具实现:
  • Prosemirror:一个用于在 web 端构建富文本编辑器的工具包
  • Remark:正确的 Markdown 解析器
  • TypeScript:以 TypeScript 编写
  • Emotion:用于构建样式的强大的 css in js 工具
  • Prism:代码块支持
  • Katex:高性能的渲染数学公式
富文本编辑器本身是一个天坑 。 虽然 ContentEditable 看起来很美好 , 但实际用起来就会发现问题层出不穷 。 因此我们基于 Prosemirror 来实现富文本编辑器 。 因为它足够成熟、久经工业的锤炼 , 并且拥有良好的架构和 API 设计 。
三、架构【程序员|任由文字肆意流淌,更自由的开源 Markdown 编辑器】Prosemirror 的核心逻辑其实类似于 React , 它通过一种函数式的数据映射来体现编辑器的 UI 和内部状态的关系 , 如图:
编辑器通过 EditorState 来保存当前状态 , 并由 EditorState 产生出 EditorView , 即 UI 视图 。 用户在 UI 视图上进行的操作最终会产生 DOM event , 例如:input 事件、click 事件 。 DOM event 事件会产生 Transaction , 代表了对 State 的修改 , 类似于 Redux 或 Vuex 中的 Action 。 这些 Transaction 会与原来的 EditorState 进行计算 , 产生新的 EditorState , 如此循环 。