Hexo标签解析

写作时的自定义标签 -> 最终的网页上的html标签

标签分两种,无内容的单一标签(Void elements)和有内容的成对标签。
单一标签的基本形式为

{% tag arg1 arg2 ... %}

成对标签的基本形式为

{% tag arg1 arg2 ... %} content {% endtag %}

在实现上分为两种,一种会直接转换,

1
2
3
4
5
function xxxTag(args,content) {
//logic
return 'htmlTag';
}
module.exports = xxxTag;

另一种会利用到context进行一定处理

1
2
3
4
5
6
module.exports = function(ctx) {
return function xxxTag(args,content) {
//logic
return 'htmlTag'
};
};

Tag采用注册机制
针对不同的解析器,根据需要传入context
可以对同一Tag解析器注册多次,可以将多个名称映射到同一解析器,实现多个名字兼容

plugins/tag/index.js
1
2
3
4
5
6
7
8
9
10
module.exports = function(ctx) {
var tag = ctx.extend.tag;

var blockquote = require('./blockquote')(ctx);
tag.register('quote', blockquote, true);
tag.register('blockquote', blockquote, true);

tag.register('gist', require('./gist'));
tag.register('iframe', require('./iframe'));
}

Tag的建模类位于extend/tag.js
Tag实现是基于nunjucks模板引擎

1
2
3
4
5
function Tag() {
this.env = new nunjucks.Environment(null, {
autoescape: false
});
}

那么所谓的注册就是对引擎进行标签自定义扩展,这就是为什么采用了{% %}的标签风格
还可以看出有无内容的标签分别对应了NunjucksBlock和NunjucksTag两个实现

1
2
3
4
5
6
7
8
9
10
11
12
13
Tag.prototype.register = function(name, fn, options) {
//...
if (options.async) {
//....
} else {
if (options.ends) {
tag = new NunjucksBlock(name, fn);
} else {
tag = new NunjucksTag(name, fn);
}
}
this.env.addExtension(name, tag);
};