admin管理员组文章数量:1615225
https://github/TooBug/wemark
链接中包含了wemark的使用说明 也包括在taro中的使用
但是wemark 在taro中有一个问题 在原生小程序中跑不存在任何的问题 这就是一个十分诡异的问题 所以我的方法是比较了remarkable.js在taro 和原生中运行状态的跟踪 发现了蹊跷 下面就是整个过程
wemark.js 中
if(this.data.type === 'wemark'){
console.log(parsedData,"wemark=====")
打印出来的parsedData 是一个空数组 进入代码后走到parser.js
this.setData({
parsedData
});
}
parser.js在执行中返回的数组是空数组
function parse(md, options){
if(!options) options = {};
var tokens = parser.parse(md, {});
console.log('tokentokens99999====',tokens)
在这里就返回了空数组
再深入代码走入remarkable.js的压缩混淆后的源码中
第一步走了这里
s.prototype.parse=function(e,t){
var r=new n(this,e,t);
console.log('parse2测ss',r.tokens)
在这里打印出来的r.tokens是有数据的 return 阻断之后是没有数据的 说明是下面的代码问题继续往this.core.process函数中走
return this.core.process(r),r.tokens
}
n.prototype.process=function(e){
var t,r,n;
//console.log(this.ruler.getRules("")[0](e),"n[t](e)0000")
// console.log(e,"e=========chulihou")
//return
// function a (e) {
//
// // e.inlineMode ? e.tokens.push({ type: "inline", content: e.src.replace(/\n/g, " ").trim(), level: 0, lines: [0, 1], children: [] }) : e.block.parse(e.src, e.options, e.env, e.tokens);
// // debugger
// console.log('e.block.parse====',e.block.parse)
// e.block.parse(e.src, e.options, e.env, e.tokens);
// };
// a(e)
console.log("22223e9999",e)
// console.log(this.ruler.getRules(""),"this.ruler.getRules(\"\")[0]")
走到这里的时候return 发现打出来的r.tokens还是空数组 但是把下面的这行代码放开后 r.tokens就有数据了
说明tokens的赋值操作还是在下面执行 可见n[t](e) 这个回调函数的作用 e就是我们markdown 传入的md文本
for(n=this.ruler.getRules(""),t=0,r=n.length;r>t;t++)n[t](e)
}
于是我们继续进入n[t](e)这个函数中去 打印出这个函数大概是这样子的
// function a (e) {
//
// // e.inlineMode ? e.tokens.push({ type: "inline", content: e.src.replace(/\n/g, " ").trim(), level: 0, lines: [0, 1], children: [] }) : e.block.parse(e.src, e.options, e.env, e.tokens);
// // debugger
// console.log('e.block.parse====',e.block.parse)
// e.block.parse(e.src, e.options, e.env, e.tokens);
// };
由于e.inlineMode是false 所以走了e.block.parse(e.src, e.options, e.env, e.tokens);的逻辑
于是我们再次进入e.block.parse(e.src, e.options, e.env, e.tokens); 调用的是原型上的方法
n.prototype.parse=function(e,t,r,n){
//debugger
console.log('进入parse函数拉===hahahhahahahhahhahah')
console.log(n,"block.parse======")
console.log('e===============e=============ee===e.indexOf(" ")>=0',e.indexOf(" ")>=0)
// var s=new o(e,this,t,r,n)
// console.log(s,"sssssssssssss")
// void this.tokenize(s,s.line,s.lineMax)
//console.log('最后测试r====',n)
//return
var s,i=0,u=0;return e?(e=e.replace(c," "),e=e.replace(a,"\n"),e.indexOf(" ")>=0&&(e=e.replace(l,function(t,r){
console.log(new o(e,this,t,r,n),"new o(e,this,t,r,n)=======")
var n;return 10===e.charCodeAt(r)?(i=r+1,u=0,t):(n=" ".slice((r-i-u)%4),u=r-i+1,n)})),
s=new o(e,this,t,r,n),void this.tokenize(s,s.line,s.lineMax)):[]
走到了这里走到 s=new o(e,this,t,r,n) 把return 断掉 输出的r依然是一个空数组 然后把void放开,发现数组有值了,简直是欣喜若狂然后就顺其自然的在void this.tokenize(s,s.line,s.lineMax))中加了一个return 之后发现数组没有值了(这些操作都是在原生小程序中打的断点 否则taro环境是不可能出现数组有值的情况的,因为代码在taro环境遇到障碍并且不报错)
这就验证了this.tokenize 的执行情况,并且把相同的代码放到了taro环境中跑,发现this.tokenize 函数根本就没有执行,而在原生中可跑,并且不return 阻断的情况下就可以输出r.tokens数组并且长度不为0,这就验证了是tokenize在taro中受阻了
那么我们看一看这个函数
这也是原型上的方法
n.prototype.tokenize=function(e,t,r){
console.log('tokenize执行1======')
for(var n,s,o=this.ruler.getRules(""),i=o.length,l=t,a=!1;r>l&&(e.line=l=e.skipEmptyLines(l),!(l>=r))&&!(e.tShift[l]<e.blkIndent);){for(s=0;i>s&&!(n=o[s](e,l,r,!1));s++);if(e.tight=!a,e.isEmpty(e.line-1)&&(a=!0),l=e.line,r>l&&e.isEmpty(l)){if(a=!0,l++,r>l&&"list"===e.parentType&&e.isEmpty(l))break;e.line=l}}}
看起来没有什么神奇的,其实这个里面ruler全局变量加载了一个函数
大概就是下面这段代码
function n(){this.ruler=new s;for(var e=0;e<i.length;e++)this.ruler.push(i[e][0],i[e][1],{alt:(i[e][2]||[]).slice()})}var s=e("./ruler"),o=e("./rules_block/state_block"),i=[["code",e("./rules_block/code")],["fences",e("./rules_block/fences"),["paragraph","blockquote","list"]],["blockquote",e("./rules_block/blockquote"),["paragraph","blockquote","list"]],["hr",e("./rules_block/hr"),["paragraph","blockquote","list"]],["list",e("./rules_block/list"),["paragraph","blockquote"]],["footnote",e("./rules_block/footnote"),["paragraph"]],["heading",e("./rules_block/heading"),["paragraph","blockquote"]],["lheading",e("./rules_block/lheading")],["htmlblock",e("./rules_block/htmlblock"),["paragraph","blockquote"]],["table",e("./rules_block/table"),["paragraph"]],["deflist",e("./rules_block/deflist"),["paragraph"]],["paragraph",e("./rules_block/paragraph")]];
只要是引入了paragraph.js 源码中这个js文件其实是在另一个文件夹中的 引入这个js主要就是生成md的文本切断分片文件 这是一个核心文件
而全局变量ruler承担了一项非常重要的工作,就是根本paragraph类型把传入的md进行分片操作 tokenize 这个函数主要的作用就是这个, 它间接的调用了paragraph.js中push tokens的方法
paragraph.js中 push tokens的方法
找了一段源码贴过来
module.exports = function paragraph(state, startLine/*, endLine*/) {
var endLine, content, terminate, i, l,
nextLine = startLine + 1,
terminatorRules;
endLine = state.lineMax;
// jump line-by-line until empty one or EOF
if (nextLine < endLine && !state.isEmpty(nextLine)) {
terminatorRules = state.parser.ruler.getRules('paragraph');
for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) {
// this would be a code block normally, but after paragraph
// it's considered a lazy continuation regardless of what's there
if (state.tShift[nextLine] - state.blkIndent > 3) { continue; }
// Some tags can terminate paragraph without empty line.
terminate = false;
for (i = 0, l = terminatorRules.length; i < l; i++) {
if (terminatorRules[i](state, nextLine, endLine, true)) {
terminate = true;
break;
}
}
if (terminate) { break; }
}
}
content = state.getLines(startLine, nextLine, state.blkIndent, false).trim();
state.line = nextLine;
if (content.length) {
state.tokens.push({
type: 'paragraph_open',
tight: false,
lines: [ startLine, state.line ],
level: state.level
});
state.tokens.push({
type: 'inline',
content: content,
level: state.level + 1,
lines: [ startLine, state.line ],
children: []
});
state.tokens.push({
type: 'paragraph_close',
tight: false,
level: state.level
});
}
return true;
};
},
说着说着就跑题了,那么问题找到了,我们应该如何解决这个问题呢,我发现js文件中为啥要用void呢,虽然void在原生小程序中不报错,是不是说taro把void这种保留字禁用了呢 如果是这样的话 那么有它的道理,
于是我把void去掉直接通过原型链的查找机制找到原型上的方法即可 ,可能代码比较老,所以容易出现问题
void this.tokenize(s,s.line,s.lineMax)) 改成了this.tokenize(s,s.line,s.lineMax))
然后在taro环境中顺利的打印出来了r.tokens 我欣喜若狂 这真是一次十分艰难的代码跟踪
不过总算是把问题解决了,我也随机在npm发布了demo 支持taro版本的没有bug的 markdown 解析器 想要的或者是在taro中使用markdown解析的关注我
我的微信号是:gwd1991
}
后续又发现很多markdown文章不能展示的情况
继续删除了remarkable.js中的响应void
改动如下
(r=e.cacheGet(o))>0)return void(e.pos=r);
去掉return 前端的void 后正常返回tokes数组
return void e.cacheSet(o,e.pos);
去掉后为
return e.cacheSet(o,e.pos);
版权声明:本文标题:wemark 在taro环境解析md失效 原生小程序正常 原因是remarkable.js源码使用了void js保留字 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1728686856a1169570.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论