關於for-editor的擴展開發及markedjs語法擴展的心得

關於for-editor

開始接觸for-editor是由於想本身寫一個基於Git的支持markdown的筆記本PC應用,經常使用開發框架是React、在PC端的開發工具的選擇上選擇了吃內存狂魔electron,就這樣抱着能不造輪子就不造輪子的原則開始使用了for-editor(雖然以後沒有打算繼續開發)。for-editor若是對於語法的支持沒有過高的要求的話,是一個很是優秀、簡潔的編輯器組件。支持Tex渲染插入、mermaid流程圖的支持、高級markdown或者擴展的markdown語法,隨着需求的提高就準備了開始本身擴展語法之路,固然其中發現了不少須要優化和修改的地方。html

開發之路

通讀源碼

源碼能夠從for-editor中查看。webpack

首先,閱讀package.jsonpackage.json是全部React組件開發必不可少的環節,在此以前仍是須要足夠了解工程的README.md的。在package.json裏,源工程對於markdown解析所用的引擎爲marked.jshighlight.js。在以前瞭解markdown --> HTML的渲染學習的時候所用的是marked.js,好處是足夠簡潔,壞處是語法不多而且擴展要求並不低。git

其次,對於源碼結構的解讀。dist爲生成產物,doc爲相關文檔,example爲演示文檔,src爲源碼目錄,webpack爲配置項。在src下有componentslibindex.tsxcomponents爲工具欄的組件,lib是開發的依賴和功能源碼,index.tsx爲總體的頁面結構。github

發現的問題

這裏提到的問題其實有一些是尚未徹底修復的,有些問題真的存在了不少年了,至今我也沒能想到比較好的解決辦法。

響應式佈局

在現代web開發中,響應式佈局對於用戶體驗來講是很是好的,可是在訪問速度上相比加載速度會稍微慢一些。針對於高標準的用戶體驗,我選擇了犧牲掉一些訪問速度,固然對於純的經過CSS實現響應式佈局在某些時候根本達不到好的效果,是須要JavaScript來加buff的,這也爲以後的開發其實還挖了一個坑,對此我不得不作出妥協,徹底的響應式目前看來是作不到的。在下面,我也會闡述具體的坑究竟是什麼。web

響應式佈局方面我作出的優化是針對900px這個標準進行的分割,隨着工具欄功能的拓展,本來工具欄的佈局會溢出。所以對於沒有二級菜單的工具欄button,我選擇寫在了more裏,而且另開了for-mobilefor-pc,使用了flex佈局來處理寬度不夠換行處理的優化措施。在下一個坑沒有遇到以前,這個方案我以爲解決的還算不錯。(固然開了新得分支,仍是被提了issue,主要是他遇到的瀏覽器尺寸在我測試的時候真的沒有發現任何問題,很迷惑)正則表達式

mermaid的引入

這是我幾個月都沒有解決的問題,多是打開方式不太對吧。。。參考了mermaidAPI和與mermaid開發者交流提了issue可是始終沒有解決。難道mermaid真的是隻能用已存在DOM節點來作渲染的嗎?但願能有大佬帶我深刻了解一下。mermaid的渲染要寫在主組件的生命週期裏面,可是就我剛剛說的,若是已知存在,在何時插進去來觸發渲染?最後我選擇了原樣插入,而後再觸發渲染的方式,當我滿心歡喜以爲一切都能如願的時候。我發現真的能不能渲染出來都是薛定諤的貓:(而後不得不放棄,想一想也真的可能跟後面那個深坑有關係,總有辦法能解決這個問題,而後參考過CSDN的HTML代碼,也就是我後來的考慮的深坑。對此,我移除了mermaid的渲染支持。json

修復js對於二級菜單的控制

感謝@ivanandonov的issue,以前我並不太以爲點擊關掉二級菜單很重要,其實也就是添加個關掉二級菜單的事件,問題不大。瀏覽器

拓展marked.js的語法

這是本部分最核心的內容了。如何去擴展marked.js的語法???我看到網上有不少小夥伴嘗試去擴展語法,可是也有很多選擇了放棄。markdown

若是你想嘗試去擴展語法,熟讀marked.js使用指南marked.js源碼和實現邏輯,固然還須要寫正則表達式:)框架

marked.js最牛逼的部分就在於正則表達式,就不重複匹配的問題,如何去用正則表達式去表示?所以重寫renderer的時候我參考了不少源碼部分的內容,這裏就不針對marked.js詳細展開介紹了,我只寫一寫我到底作了哪些事。

  • 抽離highlight.js。在原項目發現的問題之一就是——我如何去讓使用者自行決定高亮的代碼類型?我總不能把全部的語言都註冊一遍吧?!不但增長了代碼量,還需求不是很大,因此我選擇了把highlight.js依賴給移除掉。讓使用者傳入Hljs.highlightAuto這個函數,其餘的本身引入highlight.js而後本身註冊就完事了。
  • 引入emojiTexdiff語法、mark作行內高亮。這就涉及了很多的正則表達式,尤爲是在mark這個渲染上,你總不能把每一句都拿正則循環跑吧,根本不實際。因此得先把高亮塊抽離出來而後再排回去,而且不能涉及須要使用的非特殊字符。感興趣的小夥伴能夠參考marked.ts這個部分的源碼。對於相似```這種就是對於code塊的解析,若是是行內嵌入或者自定義渲染塊呢就在paragraph的部分進行重寫renderer就行了,可是記得必定要看源碼對應的html的標籤。

擴展渲染的錨點和大綱

渲染的錨點就是重寫heading部分的HTML,不贅述了就是添加一個a標籤就能解決的事情。大綱、目錄、TOC,一個東西須要用到marked.js提供的解析器lexer,提取heading部分和深度,而後來寫樣式部分。

深坑——如何去調整textarea的高度

這一切的問題仍是來源於,當我使用分欄的功能。我發現記行號並不正確,而且textarea的部分並不能很好的解決高度問題,由於高度不足以顯示所有的內容。爲何overflow: hidden其實我在不斷優化這個問題的時候也能體會到,由於外部的滾動條須要與行號對齊。

  • 修改一:換掉計算行號的方式。源代碼的計算方式是經過計算\n來實現的,貌似vscode的markdown也是這麼實現的,可是就優化而言textarea對於行號樣式能有vscode這樣的調整我是沒有發現能有什麼辦法能夠作到的。所以我也考慮了不少辦法去優化這個問題,甚至重構編輯器。在目前2.x.x的版本中,我已經換成了根據textarea的高度來計算行號了。
  • 修改二:自適應調整textarea的高度。認真地說,這個坑都坑了多少年了,不知道坑過多少人,知乎還有不少的討論。其實改起來也不算難,就是把height: auto,而後動態調整高度等於scrollHeight。而後我選擇了把計算行號在從新計算高度的函數中進行了調用。看起來,everything is ok了是吧?:)驚喜的是當分欄激活的時候scrollHeight並非會增大,是會減少的,沒想到吧。而後我只能選擇目前來講我能提供的最優的解決方案,僅當分欄關掉的時候計算高度,而後經過修改值就能夠作到精確計算。原做者還提供了fontSize這個可選項,爲此我去了解了line-heightfont-size之間的關係,具體的源碼請參考index.tsxreHeight部分的源碼。其實我還考慮過,根據上一時刻的面積除當前時刻的寬度來計算高度的,聽起來是真的很美好。實際狀況是,當你切換過快的時候,讀取到的面積並不許確,所以這個方法就是理想很豐滿,現實很骨感的問題。
  • 爲何不考慮去用可編輯div重寫?下次必定,我是準備在3.x.x的版本重構的,可是我目前沒有這麼多時間去考慮這個問題了,是真的很麻煩。

心得感悟

小小的富文本編輯器居然如此複雜,我忽然發現我是想慢慢嘗試去實現word的最基礎的功能。在拓展for-editor的過程當中我學到了不少根據教程根本是不可能學到的實際開發問題,爲此我付出了很長的事件去研究源碼,固然也去開始適應TypeScript來作開發。使用開源項目不是減小工做量,很大程度上其實增長了很多學習成本。

若是喜歡for-editor-herb我這個分支呢,請給原項目一個star。

相關文章
相關標籤/搜索