diff options
Diffstat (limited to 'lib/template/index.js')
-rw-r--r-- | lib/template/index.js | 83 |
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; |