update readme

This commit is contained in:
dntzhang 2019-04-09 10:02:51 +08:00
parent f7578a79c0
commit e84d88ca35
2 changed files with 118 additions and 0 deletions

BIN
assets/comi-token.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

View File

@ -130,5 +130,123 @@ Page({
综合上面信息,放弃 rich-text决定基于 wxParse + remarkable 二次开发,移除 showdownjs。Comi 需要 remarkable 的高性能和灵活性。markdown 会持久化存在 db 在小程序内运行时转换成 wxml所以对性能还是有一定要求。
### 劫持 prismjs tokens
```js
tokens: function (text, grammar, language) {
var env = {
code: text,
grammar: grammar,
language: language
};
_.hooks.run('before-tokenize', env);
env.tokens = _.tokenize(env.code, env.grammar);
_.hooks.run('after-tokenize', env);
for (var i = 0, len = env.tokens.length; i < len; i++) {
var v = env.tokens[i]
if (Object.prototype.toString.call(v.content) === '[object Array]') {
v.deep = true
this._walkContent(v.content)
}
}
return env.tokens
},
```
这段代码增加 tokens 方法到 prismjs 中,原库自带的 prism.highlight 的会把 tokens 转成 html因为我们的目标的 wxml所以这里提前把 tokens
作为方法返回值。当然还做了一件事,就是扩展了 token item 的 deep 属性来决定是否需要继续向下遍历生成 wxml。
原始的 jsx:
```js
render() {
const { tks } = this.data
return (
<view class='pre language-jsx'>
<view class='code'>
{tks.map(tk => {
return tk.deep ? <text class={'token ' + tk.type}>{
tk.content.map(stk => {
return stk.deep ? stk.content.map(sstk => {
return <text class={'token ' + sstk.type}>{sstk.content || sstk}</text>
}) : <text class={'token ' + stk.type}>{stk.content || stk}</text>
})}</text> : <text class={'token ' + tk.type}>{tk.content || tk}</text>
})}
</view>
</view>
)
}
```
jsx 编译出生成的 wxml把这段 wxml 嵌入到 wxparse 里:
```html
<!-- 千万 不要格式化下面的 wxml不然 text 嵌套 text 导致换行全部出来了 -->
<template name="wxParseCode">
<view class="pre language-jsx">
<view class="code">
<block wx:for="{{item.tks}}" wx:for-item="tk">
<block wx:if="{{tk.deep}}"><text class="{{'token ' + tk.type}}"><block wx:for="{{tk.content}}" wx:for-item="stk"><block wx:if="{{stk.deep}}"><text class="{{'token ' + sstk.type}}" wx:for="{{stk.content}}" wx:for-item="sstk">{{sstk.content || sstk}}</text>
</block>
<block wx:else><text class="{{'token ' + stk.type}}">{{stk.content || stk}}</text>
</block>
</block>
</text>
</block>
<block wx:else><text class="{{'token ' + tk.type}}">{{tk.content || tk}}</text>
</block>
</block>
</view>
</view>
</template>
```
这段 wxml 不能进行格式化美化,不然多出许多换行符,因为 text 嵌套 text 会保留换行符!!
修改 wxparse 里的分支逻辑:
```html
<block wx:elif="{{item.tagType == 'block'}}">
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<block wx:if="{{item.tag == 'pre'}}">
<template is="wxParseCode" data="{{item}}" />
</block>
<block wx:elif="{{item.tag != 'pre'}}" >
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse1" data="{{item}}" />
</block>
</block>
</view>
</block>
```
`item.tag``pre` 的时候使用 wxParseCode 模板,数据传入 item。item 的数据从哪里来?
先修改 md 渲染器为 Remarkable:
```js
} else if (type == 'md' || type == 'markdown') {
var converter = new Remarkable()
var html = converter.render(data)
transData = HtmlToJson.html2json(html, bindName);
}
```
使用上面的 prism.tokens 计算出代码片段的 tokens用户 wxparse 的模板渲染:
```js
function transPre(transData) {
transData.nodes.forEach((node, index) => {
if (node.tag == 'pre') {
var lan = 'markup'
if (node.nodes[0].classStr) {
lan = node.nodes[0].classStr.split(' ')[0].replace('language-', '')
}
var tks = prism.tokens(node.nodes[0].nodes[0].text, prism.languages[lan], lan)
transData.nodes[index].tks = tks
}
})
}
```