自從我開(kāi)始開(kāi)發(fā)MarkNote 之后溶握,一直在琢磨怎么讓markdown寫(xiě)得更簡(jiǎn)單蒸播。
一種方式是支持語(yǔ)法高亮,對(duì)常用的markdown語(yǔ)法提供輔助胀屿。不過(guò)這個(gè)特性一直在開(kāi)發(fā)計(jì)劃中優(yōu)先級(jí)不高包雀,所以遲遲未能實(shí)現(xiàn)。
今天有點(diǎn)心情葡兑,研究了一把赞草,用一種比較簡(jiǎn)單的方式實(shí)現(xiàn)了。下面是簡(jiǎn)單的演示效果房资。
沒(méi)有做成 UITextView的子類(lèi)轰异,而是作為一個(gè)category來(lái)實(shí)現(xiàn)的,這樣對(duì)使用者而言侵入性更小一些婴削,使用起來(lái)也更方便牙肝。
Talk is cheap, show me the code!
下面簡(jiǎn)單解釋一下:
SynctaxRule
首先定義了一個(gè)語(yǔ)法規(guī)則類(lèi)SyntaxRule
嗤朴,它用來(lái)容納正則表達(dá)式虫溜,以及對(duì)應(yīng)的樣式。樣式用NSDictionary來(lái)容納衡楞。也就是說(shuō)如果文本匹配express,則對(duì)它應(yīng)用style里面的樣式歧杏。
類(lèi)很簡(jiǎn)單迷守,聲明如下:
@interface SyntaxRule
@property (readonly) NSRegularExpression* express;
@property (readonly) NSDictionary* styles;
-(instancetype) initWithExpress:(NSRegularExpression*) exp Styles:(NSDictionary*) styles;
@end
SyntaxOccurance
這個(gè)類(lèi)用來(lái)代表解析后的結(jié)果:記錄文本的位置,記錄需要對(duì)它應(yīng)用的樣式:
@interface SyntaxOccurance
@property(readonly) NSRange range;
@property (readonly) NSDictionary* styles;
語(yǔ)法解析和渲染
解析過(guò)程比較直接:
- 構(gòu)建markdown 的語(yǔ)法規(guī)則隊(duì)列, 每一個(gè)規(guī)則有表達(dá)式和需要應(yīng)用的樣式凯力;
- 對(duì)文本急膀,遍歷規(guī)則卓嫂。針對(duì)每一個(gè)規(guī)則尋找文本中匹配的實(shí)例,將其位置和規(guī)則的樣式構(gòu)建SyntaxOccurance對(duì)象晨雳。
- 最后餐禁,把所有的SyntaxOccurance對(duì)象直接轉(zhuǎn)換為
NSAttributedString
, 賦予UI組件進(jìn)行顯示。在這里帮非,我的例子中用的是UITextView,其他支持NSAttributedString的UI組件也是可以用的筑舅。
所有核心的代碼直接扔到了 github 上陨舱。如有任何改進(jìn)意見(jiàn),還望多多指教误墓。