最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • markdown 自定义的思考

    正文概述 掘金(HerbertHe)   2021-02-08   520

    写在前面的

    已经记不清什么时候开始接触的markdown了,好像是从我的一个学长做了我们学校的大数据协会论坛开始的。如果我没记错的话用的还是b3log的开源项目,应该是使用的Symphony。后来听学长说太复杂了,维护无从下手然后删库跑路了?

    也正是他画的这个饼,让我从零开始设计一个社区给不同学科、不同专业的同学来使用,之前实现过的版本并不是很满意(应该在我的链滴帖子里还能找到),然后又开始了重构之路。也正是不断的与markdown不同的编辑器接触,也让我对marked.js、markdown-it、for-editor、lute、vditor等等的编辑器、编译器、渲染器有了很多的接触,对于markdown及其拓展语法有了各种奇奇怪怪的想法

    for-editor-herb

    for-editor是一个UI设计非常不错的编辑器,它的底层解析引擎为marked.js。marked.js对于markdown的解析渲染在前端非常有名,并且在很多的编辑器上面也得到了应用。for-editor很轻、很小、很美,但是也避免不了出现了不少的bug,也不支持很多的features。当时只算是个开源项目的萌新,给作者提PR没有得到回复,然后给作者发邮件还是没有回复23333我明显感觉到作者好像无意再继续维护下去了,在issues里面也帮助了一些老哥解决了一些问题。

    直到有个老哥建议我不如去自己新开一个仓库,然后自己来打包发布2333 其实吧,当时做前端顶多算个页面仔,也就是自己写写页面这个样子,压根也没接触过npm的库咋发布,然后就试错硬着头皮来呗。修复了很多的bug,一度怀疑人生?尤其是那个编辑器-简直是噩梦,有兴趣的同学可以了解一下前端如何实现一个富文本编辑器?我当时一度怀疑我是不是在试图写一个word!!在编辑器开发里其实说问题吧,多也不多,也就是怎么撑开textarea、怎么控制焦点、怎么获取选区这点问题?当然这只是开个玩笑,实操起来真的是怀疑人生。

    for-editor计算行号就明显有个问题,它的行号是基于 \n 来计算的,这根本是不准确的。在打开和关闭渲染的时候由于textarea的宽度会发生改变。这就直接会导致,其实字它会换行,其实这跟行号就完全不匹配了。后来我的改进方案是获取容器的实际高度,然后根据字高来算实际的行数。一般默认的字体大小 font-size: 16px; ,然后明面上解决了这个问题,但是还是没能解决开关渲染导致的不准确,因为根本不会触发height发生改变。。。这个很大程度上跟设计机制有关系(随便看一看HTML就知道问题了),不过整体体验影响还可以,虽然一度让我想重构整个编辑器。愚以为vscode的体验真的是神仙,vscode其实知道的都知道是基于electron开发的,叹为观止。。。

    上面就是举个例子,在for-editor里面也就实现了下面的一些功能,好像有老哥还把这个用于项目了?

    • 更多的工具栏按钮
    • 支持数学公式的渲染
    • 支持响应式布局
    • 支持大纲跳转锚点
    • 支持大纲直接生成插入
    • 内置简繁体中文、英文和日文的支持
    • 支持自定义支持编辑器国际化
    • 支持GitHub Diff语法渲染(这个vditor好像并没有完全支持)
    • 支持自定义注册代码高亮的语言类型
    • 支持emoji短码渲染绘文字emoji
    • 支持==markdown== 语法行内高亮

    其实我之前还准备支持mermaid的,但是之前我一直没有解决渲染的问题,没找到渲染的时机,后来放弃支持了。到后来我其实比较抗拒维护这个项目了,因为我能明显感觉到渲染越来越慢。在这个项目的issue里,也有老哥给我安利过vditor,但是他貌似不会在React里面用emmm。这个项目我几乎调整了80%的代码结构,有一些问题不是很好修复,只能寄希望于重构? 但是当时又在同步写着pyvm,没有想法继续重构下去。后来业务代码越来越多就没有继续了,被我Achieved了,有4个fork,应该还有老哥还在维护,项目可以在 for-editor-herb 体验。

    在这个项目的开发中,我为了实现一些解析语法去阅读了marked.js的源码。marked.js整个项目的灵魂在于正则表达式,里面的正则表达式写的非常非常厉害。在部分features实现的时候也参考了,marked.js一直到高级使用部分都非常非常熟悉。但是,性能和维护永远是最大的问题。

    lute

    先写lute的原因是vditor我一直在不断地关注着,并且一直发现问题和提feature疯狂“作妖”?希望 @Vanessa V姐不会觉得我超级烦?

    接触lute的原因是有一些feature依靠vditor没办法实现。举个例子,在React Native中如何实现markdown渲染?难道是套一个WebView加载H5?虽然在某些场景不得不去这么实现,比如依赖KaTeX做数学公式渲染、abcjs做五线谱渲染,要不就自己再写一个库?emmm WebView会有很多的限制,而且其实在移动端做markdown即时渲染的体验不会很好。即使是GitHub官方的APP也没有实现,然后我的眼光就放到了lute的身上23333

    lute是基于编译原理使用go开发的,刚好一不小心之前自学过golang,然后开始研究lute。看的很浅显,并没有关注生成AST的部分,自己关注的主要是在渲染的处理上。lute关于内部实现方面没有文档,只能自己去看源码。lute的代码结构设计很优秀,很容易上手去阅读定位具体的问题和实现的位置。

    分析需求和具体实现:基于lute直接实现组件渲染其实是不实际的,即使后来vditor支持了自定义渲染器,但是其实仍然是string类型的。而React Native的组件是JSX,所以我需要一棵树,自己根据这棵树来遍历递归渲染。很遗憾,lute其实并没有提供这个方法,lute并不是一个纯粹的解析器,而是同时是一个渲染器,直接生成了DOM!如果你尝试在js里面调用lute暴露的某些在godoc有的方法,会直接报错。

    其实,lute的节点细分比vditor多很多,好像是有一百四十多个。并且随着特性的不断增加,这个数量还在增加。最后还是实现了“这棵树”的输出,自lute v1.7.1之后支持,是 lute.RenderJSON() 这个方法。这棵树实现了vditor绝大多数支持的语法输出,但其实vditor有很多很多的渲染都是在前端完成的。其实依靠这个方法,是可以自行实现与vditor兼容的一个纯粹的渲染器,可以自行看lute的文档 如何使用

    当我开始基于lute写npm包的时候,发现了一个很严重的问题。lute的包太大了,打包失败。lute是通过gopherjs打包成js的,没办法拆包。上文提到lute其实并不是一个纯粹的解析器,包含了渲染的部分,不知道 @88250 D哥有没有计划把解析的部分单独分离出去,新成立一个极高效率的markdown解析器的项目emmm

    如果你想要使用lute自定义渲染器,或者写个库什么的,这并不影响你在web端的使用。可以参考rollup外部依赖的这部分,通过CDN外部引入问题不大的,只是把lute打包会出现问题而已。

    vditor

    刚刚查了一下,在vditor总共提过9个issues,开始提的问题是极蠢的,对8起,浪费V姐的时间了。不过好像我提的好几个issue后来的版本实现了2333。比如这个 使用hint at方法报错 ,我希望通过拓展 @ 这个方法,实现at的并不只是一个用户,甚至是可以引用一篇文章等。

    不过有一说一,我回顾了一下我的issue还是觉得有一些是真的low?vditor的源码看了一部分,有的部分还是很有意思的,我也知道了vditor为什么有的方法那么实现。vditor的features更新速度总是比文档快很多,如果想尝鲜之类的话,建议去阅读源码(手动滑稽)

    不过,这几天发现vditor有一个问题我还是感觉挺严重的。当vditor和SSR一起使用的时候,可能会导致页面崩溃,甚至是浏览器崩溃。当你在sv模式下输入iframe这个HTML标签,可能会导致一些问题。具体讨论可以看这个issue #918 ,需求是在这个issue #906 提出的。

    需要提醒把vditor当作编辑器的项目,markdown原生支持HTML标签,所以除了开启vditor的安全过滤规避XSS攻击(默认打开的)之外,还需要过滤iframe这个标签!如果是论坛等交互式网站的话,可能无法控制用户通过iframe植入广告甚至是非法网站!

    iframe渲染这个需求,其实实现起来并不简单,需要尤其注意过滤iframe的domain和减少iframe导致的GET请求,有的引用网站不排除有访问的风控。在上面issue的讨论里我提供了两种思路,目的就是为了iframe的请求和过滤非法域名,我已经自行实现了第一种思路,依赖下面介绍的库实现起来其实非常简单。其实就是延时渲染或者防抖,这些其实在前端优化里面都有实际的应用,每个人都有不同的实现方式,不赘述了。

    codeblock-iframe语法

    这是我在上面的思考中提出的一种语法,也许之前可能有人提也能不一定的。方法特别简单,即把iframe当作代码块处理,遵循TOML的语法,这样对代码侵入很小。

    基于这个思想,我写了两个库分别支持了webpack等打包工具的调用和web端直接通过script进行引用,并且为docsify写了插件支持这种语法。

    转化过程可以在这个demo里体验 demo

    docsify的使用在这个demo里体验 demo

    仓库地址如下

    • toml2iframe 支持webpack等打包工具
    • codeblock-iframe 支持web端通过CDN导入
    • docsify-codeblock-iframe 为docsify提供的支持插件

    Todos

    在我的脑子里,还有很多很多的feature提供给markdown进行支持,比如最近对markdown支持化学结构式很感兴趣。看了现存的极少的实现方案,感觉不怎么样,可能的话只能自己去研究了,比如zrender

    因为自己是物理系的,对公式输入很敏感所以早都基于KaTeX尝试实现了Tex

    更多的想法的话,可能会为飞书写应用或者单独开发一个PC端为协同办公提供服务。虽然飞书的云文档很好用,但是还是避免不了它还是不能支撑很多的协同文档问题。所以,为团队的项目开发的话,可能会基于vditor实现一个协同文档的服务,有想法是借鉴slack实现。目标跟思源笔记的方向完全不一样,主要协同文档、文档安全、权限控制等,实现起来的架构设计和算法还是挺难的。

    因为idea太多了,导致自己写代码的速度跟不上哈哈哈哈哈

    我的其他开源项目

    就写我认为好用的吧,其他的小插件都在我的仓库里很好找的

    • nbc 全称nuco-backend-cli 是我针对限制团队commit风格和开发有的常用需求写的命令行工具,基于golang开发,支持MacOS、Linux和Windows三端,已经投入平时的开发之中使用了,并且提供了详细的文档使用文档
    • nuco-docsify 这是为了团队项目生成文档模板的工具,支持很多feature。这样我们就不必要每一次都配置文档了,nbc 也提供了nbc docs 直接生成文档,并且可以通过nbc serve 直接启动静态预览!

    还有一些文档翻译什么的,如果你觉得好用的话给个Star嗷~哈哈哈哈


    起源地下载网 » markdown 自定义的思考

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元