summaryrefslogtreecommitdiffstats
path: root/lib/template/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/template/index.js')
-rw-r--r--lib/template/index.js83
1 files changed, 80 insertions, 3 deletions
diff --git a/lib/template/index.js b/lib/template/index.js
index 3f74267..8266572 100644
--- a/lib/template/index.js
+++ b/lib/template/index.js
@@ -64,6 +64,20 @@ function TemplateEngine(output) {
this.addBlocks(defaultBlocks);
}
+// Bind a function to a context
+// Filters and blocks are binded to this context
+TemplateEngine.prototype.bindContext = function(func) {
+ var ctx = {
+ ctx: this.ctx,
+ book: this.book,
+ output: this.output
+ };
+
+ error.deprecateField(ctx, 'generator', this.output.name, 'generator property is deprecated, use output.name instead');
+
+ return _.bind(func, ctx);
+};
+
// Interpolate a string content to replace shortcuts according to the filetype
TemplateEngine.prototype.interpolate = function(filepath, source) {
var parser = parsers.get(path.extname(filepath));
@@ -240,7 +254,7 @@ TemplateEngine.prototype.addBlock = function(name, block) {
}, context);
})
- // process the block returned
+ // Process the block returned
.then(that.processBlock)
.nodeify(callback);
};
@@ -303,9 +317,30 @@ TemplateEngine.prototype.applyBlock = function(name, blk, ctx) {
else return normBlockResult(r);
};
+// Process the result of block in a context
+TemplateEngine.prototype.processBlock = function(blk) {
+ blk = _.defaults(blk, {
+ parse: false,
+ post: undefined
+ });
+ blk.id = _.uniqueId('blk');
-// Render a string
-TemplateEngine.prototype.renderString = function(content, context, options) {
+ var toAdd = (!blk.parse) || (blk.post !== undefined);
+
+ // Add to global map
+ if (toAdd) this.blockBodies[blk.id] = blk;
+
+ // Parsable block, just return it
+ if (blk.parse) {
+ return blk.body;
+ }
+
+ // Return it as a position marker
+ return '@%@'+blk.id+'@%@';
+};
+
+// Render a string (without post processing)
+TemplateEngine.prototype.render = function(content, context, options) {
options = _.defaults(options || {}, {
path: null
});
@@ -345,6 +380,12 @@ TemplateEngine.prototype.renderString = function(content, context, options) {
});
};
+// Render a string with post-processing
+TemplateEngine.prototype.renderString = function(content, context, options) {
+ return this.render(content, context, options)
+ .then(this.postProcess);
+};
+
// Apply a shortcut to a string
TemplateEngine.prototype.applyShortcut = function(content, shortcut) {
var regex = new RegExp(
@@ -356,6 +397,21 @@ TemplateEngine.prototype.applyShortcut = function(content, shortcut) {
});
};
+// Replace position markers of blocks by body after processing
+// This is done to avoid that markdown/asciidoc processer parse the block content
+TemplateEngine.prototype.replaceBlocks = function(content) {
+ var that = this;
+
+ return content.replace(/\@\%\@([\s\S]+?)\@\%\@/g, function(match, key) {
+ var blk = that.blockBodies[key];
+ if (!blk) return match;
+
+ var body = blk.body;
+
+ return body;
+ });
+};
+
// Apply all shortcuts to a template
TemplateEngine.prototype.applyShortcuts = function(type, content) {
return _.chain(this.shortcuts)
@@ -367,4 +423,25 @@ TemplateEngine.prototype.applyShortcuts = function(type, content) {
};
+// Post process content
+TemplateEngine.prototype.postProcess = function(content) {
+ var that = this;
+
+ return Promise(content)
+ .then(that.replaceBlocks)
+ .then(function(_content) {
+ return Promise.serie(that.blockBodies, function(blk, blkId) {
+ return Promise()
+ .then(function() {
+ if (!blk.post) return;
+ return blk.post();
+ })
+ .then(function() {
+ delete that.blockBodies[blkId];
+ });
+ })
+ .thenResolve(_content);
+ });
+};
+
module.exports = TemplateEngine;