summaryrefslogtreecommitdiffstats
path: root/lib/template.js
diff options
context:
space:
mode:
authorSamy Pesse <samypesse@gmail.com>2015-09-14 11:21:16 +0200
committerSamy Pesse <samypesse@gmail.com>2015-09-14 11:21:16 +0200
commit35c4179ca12a0287279ced0535f11237cdf606ec (patch)
tree3c33389aee37d515b2fed396f57a7cefb2eb8cad /lib/template.js
parent601ce3add380392fe9c1d598e01f05034ff058c3 (diff)
downloadgitbook-35c4179ca12a0287279ced0535f11237cdf606ec.zip
gitbook-35c4179ca12a0287279ced0535f11237cdf606ec.tar.gz
gitbook-35c4179ca12a0287279ced0535f11237cdf606ec.tar.bz2
Use block code for highlight pre/code
Cleanup correctly predefined blocks
Diffstat (limited to 'lib/template.js')
-rw-r--r--lib/template.js78
1 files changed, 67 insertions, 11 deletions
diff --git a/lib/template.js b/lib/template.js
index 8ea8038..b27be89 100644
--- a/lib/template.js
+++ b/lib/template.js
@@ -10,6 +10,11 @@ var batch = require("./utils/batch");
var pkg = require("../package.json");
var defaultBlocks = require("./blocks");
+// Normalize result from a block
+function normBlockResult(blk) {
+ if (_.isString(blk)) blk = { body: blk };
+ return blk;
+}
// The loader should handle relative and git url
var BookLoader = nunjucks.Loader.extend({
@@ -85,10 +90,8 @@ var TemplateEngine = function(book) {
this.addBlocks(defaultBlocks);
};
-// Process a block in a context
+// Process the result of block in a context
TemplateEngine.prototype.processBlock = function(blk) {
- if (_.isString(blk)) blk = { body: blk };
-
blk = _.defaults(blk, {
parse: false,
post: undefined
@@ -169,9 +172,32 @@ TemplateEngine.prototype.addFilters = function(filters) {
}, this);
};
+// Return nunjucks extension name of a block
+TemplateEngine.prototype.blockExtName = function(name) {
+ return 'Block'+name+'Extension';
+};
+
+// Test if a block is defined
+TemplateEngine.prototype.hasBlock = function(name) {
+ return this.env.hasExtension(this.blockExtName(name));
+};
+
+// Remove a block
+TemplateEngine.prototype.removeBlock = function(name) {
+ if (!this.hasBlock(name)) return;
+
+ // Remove nunjucks extension
+ this.env.removeExtension(this.blockExtName(name));
+
+ // Cleanup shortcuts
+ this.shortcuts = _.reject(this.shortcuts, {
+ block: name
+ });
+};
+
// Add a block
TemplateEngine.prototype.addBlock = function(name, block) {
- var that = this;
+ var that = this, Ext, extName;
if (_.isFunction(block)) block = { process: block };
@@ -182,12 +208,15 @@ TemplateEngine.prototype.addBlock = function(name, block) {
blocks: []
});
- var extName = 'Block'+name+'Extension';
- if (this.env.getExtension(extName)) {
+ var extName = this.blockExtName(name);
+
+ if (this.hasBlock(name) && !defaultBlocks[name]) {
this.log.warn.ln("conflict in blocks, '"+name+"' is already defined");
- return false;
}
+ // Cleanup previous block
+ this.removeBlock(name);
+
this.log.debug.ln("add block '"+name+"'");
this.blocks[name] = block;
@@ -272,11 +301,9 @@ TemplateEngine.prototype.addBlock = function(name, block) {
};
});
- var func = that.bindContext(block.process);
-
Q()
.then(function() {
- return func.call(context, {
+ return that.applyBlock(name, {
body: body(),
args: args,
kwargs: kwargs,
@@ -290,7 +317,6 @@ TemplateEngine.prototype.addBlock = function(name, block) {
};
};
-
// Add the Extension
this.env.addExtension(extName, new Ext());
@@ -299,6 +325,7 @@ TemplateEngine.prototype.addBlock = function(name, block) {
_.each(block.shortcuts, function(shortcut) {
this.log.debug.ln("add template shortcut from '"+shortcut.start+"' to block '"+name+"' for parsers ", shortcut.parsers);
this.shortcuts.push({
+ block: name,
parsers: shortcut.parsers,
start: shortcut.start,
end: shortcut.end,
@@ -312,11 +339,40 @@ TemplateEngine.prototype.addBlock = function(name, block) {
// Add multiple blocks
TemplateEngine.prototype.addBlocks = function(blocks) {
+ console.log('add blocks', blocks);
_.each(blocks, function(block, name) {
this.addBlock(name, block);
}, this);
};
+// Apply a block to some content
+// This method result depends on the type of block (async or sync)
+TemplateEngine.prototype.applyBlock = function(name, blk) {
+ var func, block, func, r;
+
+ block = this.blocks[name];
+ console.log('applyBlock', name, block);
+ if (!block) throw new Error('Block not found "'+name+'"');
+ if (_.isString(blk)) {
+ blk = {
+ body: blk
+ };
+ }
+
+ blk = _.defaults(blk, {
+ args: [],
+ kwargs: {},
+ blocks: []
+ });
+
+ // Bind and call block processor
+ func = this.bindContext(block.process);
+ r = func.call(context, blk);
+
+ if (Q.isPromise(r)) return r.then(normBlockResult);
+ else return normBlockResult(r);
+};
+
// Apply a shortcut to a string
TemplateEngine.prototype._applyShortcut = function(parser, content, shortcut) {
if (!_.contains(shortcut.parsers, parser)) return content;