summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/template.js61
-rw-r--r--test/plugins.js122
-rw-r--r--test/plugins/blocks/index.js11
3 files changed, 102 insertions, 92 deletions
diff --git a/lib/template.js b/lib/template.js
index 41362c8..d9d3a2f 100644
--- a/lib/template.js
+++ b/lib/template.js
@@ -1,13 +1,12 @@
var _ = require("lodash");
var Q = require("q");
-var path = require("path");
var nunjucks = require("nunjucks");
var escapeStringRegexp = require("escape-string-regexp");
var batch = require("./utils/batch");
var pkg = require("../package.json");
var defaultBlocks = require("./blocks");
-var BookLoader = require("./conrefs_loader")
+var BookLoader = require("./conrefs_loader");
// Normalize result from a block
function normBlockResult(blk) {
@@ -29,12 +28,12 @@ var TemplateEngine = function(book) {
// Tags
tags: {
- blockStart: '{%',
- blockEnd: '%}',
- variableStart: '{{',
- variableEnd: '}}',
- commentStart: '{###',
- commentEnd: '###}'
+ blockStart: "{%",
+ blockEnd: "%}",
+ variableStart: "{{",
+ variableEnd: "}}",
+ commentStart: "{###",
+ commentEnd: "###}"
}
}
);
@@ -63,7 +62,7 @@ TemplateEngine.prototype.processBlock = function(blk) {
});
blk.id = _.uniqueId("blk");
- var toAdd = (!blk.parse) || (blk.post != undefined);
+ var toAdd = (!blk.parse) || (blk.post !== undefined);
// Add to global map
if (toAdd) this.blockBodies[blk.id] = blk;
@@ -111,11 +110,11 @@ TemplateEngine.prototype.bindContext = function(func) {
TemplateEngine.prototype.addFilter = function(filterName, func) {
try {
this.env.getFilter(filterName);
- this.log.warn.ln("conflict in filters, '"+filterName+"' is already set");
+ this.log.warn.ln("conflict in filters, \""+filterName+"\" is already set");
return false;
} catch(e) {}
- this.log.debug.ln("add filter '"+filterName+"'");
+ this.log.debug.ln("add filter \""+filterName+"\"");
this.env.addFilter(filterName, this.bindContext(function() {
var ctx = this;
var args = Array.prototype.slice.apply(arguments);
@@ -139,7 +138,7 @@ TemplateEngine.prototype.addFilters = function(filters) {
// Return nunjucks extension name of a block
TemplateEngine.prototype.blockExtName = function(name) {
- return 'Block'+name+'Extension';
+ return "Block"+name+"Extension";
};
// Test if a block is defined
@@ -173,22 +172,22 @@ TemplateEngine.prototype.addBlock = function(name, block) {
blocks: []
});
- var extName = this.blockExtName(name);
+ extName = this.blockExtName(name);
if (this.hasBlock(name) && !defaultBlocks[name]) {
- this.log.warn.ln("conflict in blocks, '"+name+"' is already defined");
+ this.log.warn.ln("conflict in blocks, \""+name+"\" is already defined");
}
// Cleanup previous block
this.removeBlock(name);
- this.log.debug.ln("add block '"+name+"'");
+ this.log.debug.ln("add block \""+name+"\"");
this.blocks[name] = block;
- var Ext = function () {
+ Ext = function () {
this.tags = [name];
- this.parse = function(parser, nodes, lexer) {
+ this.parse = function(parser, nodes) {
var body = null;
var lastBlockName = null;
var lastBlockArgs = null;
@@ -229,7 +228,7 @@ TemplateEngine.prototype.addBlock = function(name, block) {
var bodies = [body];
_.each(block.blocks, function(blockName) {
subbodies[blockName] = subbodies[blockName] || [];
- if (subbodies[blockName].length == 0) {
+ if (subbodies[blockName].length === 0) {
subbodies[blockName].push({
args: new nodes.NodeList(),
body: new nodes.NodeList()
@@ -239,7 +238,7 @@ TemplateEngine.prototype.addBlock = function(name, block) {
bodies.push(subbodies[blockName][0].body);
});
- return new nodes.CallExtensionAsync(this, 'run', args, bodies);
+ return new nodes.CallExtensionAsync(this, "run", args, bodies);
};
this.run = function(context) {
@@ -273,12 +272,12 @@ TemplateEngine.prototype.addBlock = function(name, block) {
args: args,
kwargs: kwargs,
blocks: _blocks
- });
+ }, context);
})
// process the block returned
.then(that.processBlock)
- .nodeify(callback)
+ .nodeify(callback);
};
};
@@ -288,7 +287,7 @@ TemplateEngine.prototype.addBlock = function(name, block) {
// Add shortcuts
if (!_.isArray(block.shortcuts)) block.shortcuts = [block.shortcuts];
_.each(block.shortcuts, function(shortcut) {
- this.log.debug.ln("add template shortcut from '"+shortcut.start+"' to block '"+name+"' for parsers ", shortcut.parsers);
+ 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,
@@ -311,11 +310,11 @@ TemplateEngine.prototype.addBlocks = function(blocks) {
// 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;
+TemplateEngine.prototype.applyBlock = function(name, blk, ctx) {
+ var func, block, r;
block = this.blocks[name];
- if (!block) throw new Error('Block not found "'+name+'"');
+ if (!block) throw new Error("Block not found \""+name+"\"");
if (_.isString(blk)) {
blk = {
body: blk
@@ -330,7 +329,7 @@ TemplateEngine.prototype.applyBlock = function(name, blk) {
// Bind and call block processor
func = this.bindContext(block.process);
- r = func(blk);
+ r = func.call(ctx || {}, blk);
if (Q.isPromise(r)) return r.then(normBlockResult);
else return normBlockResult(r);
@@ -341,7 +340,7 @@ TemplateEngine.prototype._applyShortcut = function(parser, content, shortcut) {
if (!_.contains(shortcut.parsers, parser)) return content;
var regex = new RegExp(
escapeStringRegexp(shortcut.start) + "([\\s\\S]*?[^\\$])" + escapeStringRegexp(shortcut.end),
- 'g'
+ "g"
);
return content.replace(regex, function(all, match) {
return "{% "+shortcut.tag.start+" %}"+ match + "{% "+shortcut.tag.end+" %}";
@@ -350,7 +349,7 @@ TemplateEngine.prototype._applyShortcut = function(parser, content, shortcut) {
// Render a string from the book
TemplateEngine.prototype.renderString = function(content, context, options) {
- var context = _.extend({}, context, {
+ context = _.extend({}, context, {
// Variables from book.json
book: this.book.options.variables,
@@ -382,8 +381,8 @@ TemplateEngine.prototype.renderString = function(content, context, options) {
};
// Render a file from the book
-TemplateEngine.prototype.renderFile = function(filename, options) {
- var that = this, context;
+TemplateEngine.prototype.renderFile = function(filename) {
+ var that = this;
return that.book.readFile(filename)
.then(function(content) {
@@ -395,7 +394,7 @@ TemplateEngine.prototype.renderFile = function(filename, options) {
// Render a page from the book
TemplateEngine.prototype.renderPage = function(page) {
- var that = this, context;
+ var that = this;
return that.book.statFile(page.path)
.then(function(stat) {
diff --git a/test/plugins.js b/test/plugins.js
index 6d5b9de..e6df389 100644
--- a/test/plugins.js
+++ b/test/plugins.js
@@ -1,13 +1,12 @@
-var _ = require('lodash');
-var should = require('should');
-var path = require('path');
-var fs = require('fs');
+var _ = require("lodash");
+var should = require("should");
+var path = require("path");
-var Plugin = require('../lib/plugin');
+var Plugin = require("../lib/plugin");
var parsers = require("gitbook-parsers");
-var PLUGINS_ROOT = path.resolve(__dirname, 'plugins');
+var PLUGINS_ROOT = path.resolve(__dirname, "plugins");
-describe('Plugins', function () {
+describe("Plugins", function () {
var book;
before(function() {
@@ -17,7 +16,7 @@ describe('Plugins', function () {
});
});
- describe('Invalid', function() {
+ describe("Invalid", function() {
var plugin;
before(function() {
@@ -25,12 +24,12 @@ describe('Plugins', function () {
plugin.load("./invalid", PLUGINS_ROOT);
});
- it('should be detected', function() {
+ it("should be detected", function() {
should(plugin.isValid()).be.exactly(false);
});
});
- describe('Empty', function() {
+ describe("Empty", function() {
var plugin;
before(function() {
@@ -38,11 +37,11 @@ describe('Plugins', function () {
plugin.load("./empty", PLUGINS_ROOT);
});
- it('should valid a plugin', function() {
+ it("should valid a plugin", function() {
should(plugin.isValid()).be.exactly(true);
});
- it('should return an empty list of resources', function() {
+ it("should return an empty list of resources", function() {
return plugin.getResources()
.then(function(resources) {
_.each(Plugin.RESOURCES, function(resName) {
@@ -52,7 +51,7 @@ describe('Plugins', function () {
});
});
- describe('Resources', function() {
+ describe("Resources", function() {
var plugin;
before(function() {
@@ -62,45 +61,45 @@ describe('Plugins', function () {
return book.plugins.load(plugin);
});
- it('should valid a plugin', function() {
+ it("should valid a plugin", function() {
should(plugin.isValid()).be.exactly(true);
});
- describe('Website', function() {
- it('should return a valid list of resources', function() {
+ describe("Website", function() {
+ it("should return a valid list of resources", function() {
return plugin.getResources("website")
.then(function(resources) {
- resources["js"].should.have.lengthOf(1);
+ resources.js.should.have.lengthOf(1);
});
});
- it('should extend books plugins', function() {
+ it("should extend books plugins", function() {
var resources = book.plugins.resources("website");
- resources["js"].should.have.lengthOf(1);
+ resources.js.should.have.lengthOf(1);
});
});
- describe('eBook', function() {
- it('should return a valid list of resources', function() {
+ describe("eBook", function() {
+ it("should return a valid list of resources", function() {
return plugin.getResources("ebook")
.then(function(resources) {
- resources["css"].should.have.lengthOf(1);
+ resources.css.should.have.lengthOf(1);
});
});
- it('should extend books plugins', function() {
+ it("should extend books plugins", function() {
var resources = book.plugins.resources("ebook");
// There is resources from highlight plugin and this plugin
- resources["css"].should.have.lengthOf(2);
- should.exist(_.find(resources["css"], {
- path: './resources/test'
+ resources.css.should.have.lengthOf(2);
+ should.exist(_.find(resources.css, {
+ path: "./resources/test"
}));
});
});
});
- describe('Filters', function() {
+ describe("Filters", function() {
var plugin;
before(function() {
@@ -110,11 +109,11 @@ describe('Plugins', function () {
return book.plugins.load(plugin);
});
- it('should valid a plugin', function() {
+ it("should valid a plugin", function() {
should(plugin.isValid()).be.exactly(true);
});
- it('should return a map of filters', function() {
+ it("should return a map of filters", function() {
var filters = plugin.getFilters();
_.size(filters).should.equal(2);
@@ -122,22 +121,22 @@ describe('Plugins', function () {
filters.should.have.property("helloCtx");
});
- it('should correctly extend template filters', function() {
- return book.template.renderString('{{ "World"|hello }}')
+ it("should correctly extend template filters", function() {
+ return book.template.renderString("{{ \"World\"|hello }}")
.then(function(content) {
content.should.equal("Hello World");
});
});
- it('should correctly set book as context', function() {
- return book.template.renderString('{{ "root"|helloCtx }}')
+ it("should correctly set book as context", function() {
+ return book.template.renderString("{{ \"root\"|helloCtx }}")
.then(function(content) {
content.should.equal("root:"+book.root);
});
});
});
- describe('Blocks', function() {
+ describe("Blocks", function() {
var plugin;
before(function() {
@@ -149,22 +148,22 @@ describe('Plugins', function () {
var testTpl = function(str, args, options) {
return book.template.renderString(str, args, options)
- .then(book.template.postProcess)
+ .then(book.template.postProcess);
};
- it('should valid a plugin', function() {
+ it("should valid a plugin", function() {
should(plugin.isValid()).be.exactly(true);
});
- it('should correctly extend template blocks', function() {
- return testTpl('{% test %}hello{% endtest %}')
+ it("should correctly extend template blocks", function() {
+ return testTpl("{% test %}hello{% endtest %}")
.then(function(content) {
content.should.equal("testhellotest");
});
});
- it('should correctly accept shortcuts', function() {
- return testTpl('$$hello$$', {}, {
+ it("should correctly accept shortcuts", function() {
+ return testTpl("$$hello$$", {}, {
type: "markdown"
})
.then(function(content) {
@@ -172,43 +171,50 @@ describe('Plugins', function () {
});
});
- it('should correctly extend template blocks with defined end', function() {
- return testTpl('{% test2 %}hello{% endtest2end %}')
+ it("should correctly extend template blocks with defined end", function() {
+ return testTpl("{% test2 %}hello{% endtest2end %}")
.then(function(content) {
content.should.equal("test2hellotest2");
});
});
- it('should correctly extend template blocks with sub-blocks', function() {
- return testTpl('{% test3join separator=";" %}hello{% also %}world{% endtest3join %}')
+ it("should correctly extend template blocks with sub-blocks", function() {
+ return testTpl("{% test3join separator=\";\" %}hello{% also %}world{% endtest3join %}")
.then(function(content) {
content.should.equal("hello;world");
});
});
- it('should correctly extend template blocks with different sub-blocks', function() {
- return testTpl('{% test4join separator=";" %}hello{% also %}the{% finally %}world{% endtest4join %}')
+ it("should correctly extend template blocks with different sub-blocks", function() {
+ return testTpl("{% test4join separator=\";\" %}hello{% also %}the{% finally %}world{% endtest4join %}")
.then(function(content) {
content.should.equal("hello;the;world");
});
});
- it('should correctly extend template blocks with arguments', function() {
- return testTpl('{% test5args "a", "b", "c" %}{% endtest5args %}')
+ it("should correctly extend template blocks with arguments", function() {
+ return testTpl("{% test5args 'a', 'b', 'c' %}{% endtest5args %}")
.then(function(content) {
content.should.equal("test5a,b,ctest5");
});
});
- it('should correctly extend template blocks with args and kwargs', function() {
- return testTpl('{% test5kwargs "a", "b", "c", d="test", e="test2" %}{% endtest5kwargs %}')
+ it("should correctly extend template blocks with args and kwargs", function() {
+ return testTpl("{% test5kwargs 'a', 'b', 'c', d='test', e='test2' %}{% endtest5kwargs %}")
.then(function(content) {
content.should.equal("test5a,b,c,d:test,e:test2,__keywords:truetest5");
});
});
+
+ it("should correctly extend template blocks with access to context", function() {
+ return testTpl("{% set name = 'john' %}{% test6context %}{% endtest6context %}", {})
+ .then(function(content) {
+ content.should.equal("test6johntest6");
+ });
+ });
});
- describe('Blocks without parsing', function() {
+ describe("Blocks without parsing", function() {
var plugin;
before(function() {
@@ -222,21 +228,21 @@ describe('Plugins', function () {
var filetype = parsers.get(markup);
return book.template.renderString(str, args, options)
- .then(filetype.page).get('sections').get(0).get('content')
- .then(book.template.postProcess)
+ .then(filetype.page).get("sections").get(0).get("content")
+ .then(book.template.postProcess);
};
- it('should correctly process unparsable for markdown', function() {
- return testTpl('.md', '{% test %}**hello**{% endtest %}')
+ it("should correctly process unparsable for markdown", function() {
+ return testTpl(".md", "{% test %}**hello**{% endtest %}")
.then(function(content) {
content.should.equal("<p>test**hello**test</p>\n");
});
});
- it('should correctly process unparsable for asciidoc', function() {
- return testTpl('.adoc', '{% test %}**hello**{% endtest %}')
+ it("should correctly process unparsable for asciidoc", function() {
+ return testTpl(".adoc", "{% test %}**hello**{% endtest %}")
.then(function(content) {
- content.should.equal('<div class="paragraph">\n<p>test**hello**test</p>\n</div>');
+ content.should.equal("<div class=\"paragraph\">\n<p>test**hello**test</p>\n</div>");
});
});
});
diff --git a/test/plugins/blocks/index.js b/test/plugins/blocks/index.js
index 0848238..9bdbe86 100644
--- a/test/plugins/blocks/index.js
+++ b/test/plugins/blocks/index.js
@@ -39,18 +39,23 @@ module.exports = {
},
"test5args": {
process: function(blk) {
- return "test5"+blk.args.join(',')+"test5";
+ return "test5"+blk.args.join(",")+"test5";
}
},
"test5kwargs": {
process: function(blk) {
- var s = blk.args.join(',');
+ var s = blk.args.join(",");
for (var key in blk.kwargs) {
- s = s + ','+key+':'+blk.kwargs[key];
+ s = s + ","+key+":"+blk.kwargs[key];
}
return "test5"+s+"test5";
}
},
+ "test6context": {
+ process: function() {
+ return "test6"+(this.ctx.name)+"test6";
+ }
+ },
}
}; \ No newline at end of file