summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/template.js35
-rw-r--r--lib/utils/string.js5
-rw-r--r--test/plugins.js10
-rw-r--r--test/plugins/blocks/index.js5
4 files changed, 54 insertions, 1 deletions
diff --git a/lib/template.js b/lib/template.js
index ec1b391..070173c 100644
--- a/lib/template.js
+++ b/lib/template.js
@@ -4,6 +4,7 @@ var path = require("path");
var nunjucks = require("nunjucks");
var git = require("./utils/git");
+var stringUtils = require("./utils/string");
var fs = require("./utils/fs");
var pkg = require("../package.json");
@@ -65,6 +66,9 @@ var TemplateEngine = function(book) {
}
}
);
+
+ // List of tags shortcuts
+ this.shortcuts = [];
};
@@ -86,6 +90,7 @@ TemplateEngine.prototype.addBlock = function(name, block) {
var that = this;
block = _.defaults(block || {}, {
+ shortcuts: [],
end: "end"+name,
process: _.identity,
blocks: []
@@ -93,7 +98,7 @@ TemplateEngine.prototype.addBlock = function(name, block) {
var extName = 'Block'+name+'Extension';
if (this.env.getExtension(extName)) {
- this.log.warn.ln("conflict in blocks, '"+extName+"' is already defined");
+ this.log.warn.ln("conflict in blocks, '"+name+"' is already defined");
return false;
}
@@ -194,6 +199,31 @@ TemplateEngine.prototype.addBlock = function(name, block) {
// Add the Extension
this.env.addExtension(extName, new Ext());
+
+ // 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+"'");
+ this.shortcuts.push({
+ start: shortcut.start,
+ end: shortcut.end,
+ tag: {
+ start: name,
+ end: block.end
+ }
+ });
+ }, this);
+};
+
+// Apply a shortcut to a string
+TemplateEngine.prototype._applyShortcut = function(content, shortcut) {
+ var regex = new RegExp(
+ stringUtils.escapeRegex(shortcut.start) + "\\s*([\\s\\S]*?[^\\$])\\s*" + stringUtils.escapeRegex(shortcut.end),
+ 'g'
+ );
+ return content.replace(regex, function(all, match) {
+ return "{% "+shortcut.tag.start+" %}"+ match + "{% "+shortcut.tag.end+" %}";
+ });
};
// Render a string from the book
@@ -210,6 +240,9 @@ TemplateEngine.prototype.renderString = function(content, context, options) {
options = _.defaults(options || {}, { path: null});
if (options.path) options.path = this.book.resolve(options.path);
+ // Replace shortcuts
+ content = _.reduce(this.shortcuts, this._applyShortcut.bind(this), content);
+
return Q.nfcall(this.env.renderString.bind(this.env), content, context, options);
};
diff --git a/lib/utils/string.js b/lib/utils/string.js
index 72a9ca0..588f4d9 100644
--- a/lib/utils/string.js
+++ b/lib/utils/string.js
@@ -20,7 +20,12 @@ function optionsToShellArgs(options) {
.join(" ");
}
+function escapeRegex(str) {
+ return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
+}
+
module.exports = {
+ escapeRegex: escapeRegex,
escapeShellArg: escapeShellArg,
optionsToShellArgs: optionsToShellArgs,
toLowerCase: String.prototype.toLowerCase.call.bind(String.prototype.toLowerCase)
diff --git a/test/plugins.js b/test/plugins.js
index 3c60a20..43ce497 100644
--- a/test/plugins.js
+++ b/test/plugins.js
@@ -98,6 +98,16 @@ describe('Plugins', function () {
);
});
+ it('should correctly accept shortcuts', function(done) {
+ qdone(
+ books[0].template.renderString('$$hello$$')
+ .then(function(content) {
+ assert.equal(content, "testhellotest");
+ }),
+ done
+ );
+ });
+
it('should correctly extend template blocks with defined end', function(done) {
qdone(
books[0].template.renderString('{% test2 %}hello{% endtest2end %}')
diff --git a/test/plugins/blocks/index.js b/test/plugins/blocks/index.js
index b8f72fe..0a02ff7 100644
--- a/test/plugins/blocks/index.js
+++ b/test/plugins/blocks/index.js
@@ -3,6 +3,11 @@ var assert = require("assert");
module.exports = {
blocks: {
"test": {
+ shortcuts: {
+ parsers: ["markdown"],
+ start: "$$",
+ end: "$$"
+ },
process: function(blk) {
return "test"+blk.body+"test";
}