diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/models/templateBlock.js | 23 | ||||
-rw-r--r-- | lib/models/templateEngine.js | 13 | ||||
-rw-r--r-- | lib/output/generatePage.js | 7 | ||||
-rw-r--r-- | lib/templating/index.js | 3 | ||||
-rw-r--r-- | lib/templating/postRender.js | 28 | ||||
-rw-r--r-- | lib/templating/replaceBlocks.js | 34 |
6 files changed, 106 insertions, 2 deletions
diff --git a/lib/models/templateBlock.js b/lib/models/templateBlock.js index cce636e..4094b89 100644 --- a/lib/models/templateBlock.js +++ b/lib/models/templateBlock.js @@ -9,12 +9,24 @@ var NODE_ENDARGS = '%%endargs%%'; var blockBodies = {}; var TemplateBlock = Immutable.Record({ + // Name of block, also the start tag name: String(), + + // End tag, default to "end<name>" end: String(), + + // Function to process the block content process: Function(), + + // List of String, for inner block tags blocks: Immutable.List(), + + // List of shortcuts to replace with this block shortcuts: Immutable.List(), + + // Function to execute in post processing post: null, + parse: true }, 'TemplateBlock'); @@ -208,6 +220,7 @@ TemplateBlock.prototype.handleBlockResult = function(result) { if (is.string(result)) { result = { body: result }; } + result.name = this.getName(); return result; }; @@ -251,6 +264,16 @@ TemplateBlock.indexBlockResult = function(blk) { }; /** + Get a block results indexed for a specific key + + @param {String} key + @return {Object|undefined} +*/ +TemplateBlock.getBlockResultByKey = function(key) { + return blockBodies[key]; +}; + +/** Create a template block from a function or an object @param {String} blockName diff --git a/lib/models/templateEngine.js b/lib/models/templateEngine.js index 9a18bd4..28322ea 100644 --- a/lib/models/templateEngine.js +++ b/lib/models/templateEngine.js @@ -43,6 +43,19 @@ TemplateEngine.prototype.getContext = function() { }; /** + Return a block by its name (or undefined) + + @param {String} name + @return {TemplateBlock} +*/ +TemplateEngine.prototype.getBlock = function(name) { + var blocks = this.getBlocks(); + return blocks.find(function(block) { + return block.getName() === name; + }); +}; + +/** Return a nunjucks environment from this configuration @return {Nunjucks.Environment} diff --git a/lib/output/generatePage.js b/lib/output/generatePage.js index 4507f2e..113bf22 100644 --- a/lib/output/generatePage.js +++ b/lib/output/generatePage.js @@ -14,6 +14,7 @@ var createTemplateEngine = require('./createTemplateEngine'); */ function generatePage(output, page) { var book = output.getBook(); + var engine = createTemplateEngine(output); return Parse.parsePage(book, page) .then(function(resultPage) { @@ -34,13 +35,17 @@ function generatePage(output, page) { // Render templating syntax .then(function(content) { - var engine = createTemplateEngine(output); return Templating.render(engine, filePath, content); }) // Render page using parser (markdown -> HTML) .then(parser.page).get('content') + // Post processing for templating syntax + .then(function(content) { + return Templating.postRender(engine, content); + }) + // Return new page .then(function(content) { return resultPage.set('content', content); diff --git a/lib/templating/index.js b/lib/templating/index.js index 312146a..3a8f989 100644 --- a/lib/templating/index.js +++ b/lib/templating/index.js @@ -1,4 +1,5 @@ module.exports = { - render: require('./render') + render: require('./render'), + postRender: require('./postRender') }; diff --git a/lib/templating/postRender.js b/lib/templating/postRender.js new file mode 100644 index 0000000..6928e82 --- /dev/null +++ b/lib/templating/postRender.js @@ -0,0 +1,28 @@ +var Promise = require('../utils/promise'); +var replaceBlocks = require('./replaceBlocks'); + +/** + Post render a template: + - Execute "post" for blocks + - Replace block content + + @param {TemplateEngine} engine + @param {String} content + @return {Promise<String>} +*/ +function postRender(engine, content) { + var result = replaceBlocks(content); + + return Promise.forEach(result.blocks, function(blockType) { + var block = engine.getBlock(); + var post = block.getPost(); + if (!post) { + return; + } + + return post(); + }) + .thenResolve(result.content); +} + +module.exports = postRender; diff --git a/lib/templating/replaceBlocks.js b/lib/templating/replaceBlocks.js new file mode 100644 index 0000000..4b1c37f --- /dev/null +++ b/lib/templating/replaceBlocks.js @@ -0,0 +1,34 @@ +var Immutable = require('immutable'); +var TemplateBlock = require('../models/templateBlock'); + +/** + Replace position markers of blocks by body after processing + This is done to avoid that markdown/asciidoc processer parse the block content + + @param {String} content + @return {Object} {blocks: Set, content: String} +*/ +function replaceBlocks(content) { + var blockTypes = new Immutable.Set(); + var newContent = content.replace(/\{\{\-\%([\s\S]+?)\%\-\}\}/g, function(match, key) { + var replacedWith = match; + + var block = TemplateBlock.getBlockResultByKey(key); + if (block) { + var result = replaceBlocks(block.body); + + blockTypes = blockTypes.add(block.name); + blockTypes = blockTypes.concat(result.blocks); + replacedWith = result.content; + } + + return replacedWith; + }); + + return { + content: newContent, + blocks: blockTypes + }; +} + +module.exports = replaceBlocks; |