From 65fa3b18707e46ba705f9d573b94c0afabd9237f Mon Sep 17 00:00:00 2001 From: Xaxatix Date: Mon, 4 May 2015 18:05:51 +0300 Subject: [PATCH 1/4] Sub-directory support --- index.js | 242 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 149 insertions(+), 93 deletions(-) diff --git a/index.js b/index.js index 6ec8791..e97200d 100644 --- a/index.js +++ b/index.js @@ -28,116 +28,172 @@ */ var fs = require("fs"), - doT = module.exports = require("./doT"); + path = require("path"), + doT = module.exports = require("./doT"); doT.process = function(options) { - //path, destination, global, rendermodule, templateSettings - return new InstallDots(options).compileAll(); + //path, destination, global, rendermodule, templateSettings + return new InstallDots(options).compileAll(); }; function InstallDots(o) { - this.__path = o.path || "./"; - if (this.__path[this.__path.length-1] !== '/') this.__path += '/'; - this.__destination = o.destination || this.__path; - if (this.__destination[this.__destination.length-1] !== '/') this.__destination += '/'; - this.__global = o.global || "window.render"; - this.__rendermodule = o.rendermodule || {}; - this.__settings = o.templateSettings ? copy(o.templateSettings, copy(doT.templateSettings)) : undefined; - this.__includes = {}; + this.__global = o.global || "window.render"; + this.__rendermodule = o.rendermodule || {}; + this.__settings = o.templateSettings ? copy(o.templateSettings, copy(doT.templateSettings)) : undefined; + this.__includes = {}; + this.__subDirectories = o.subDirectories || false; + this.__path = o.path ? [o.path] : ["./"]; + if (this.__path[0][this.__path[0].length - 1] !== '/') { + this.__path[0] += '/'; + } + this.__destination = o.destination || this.__path[0]; + if (this.__destination[this.__destination.length - 1] !== '/') { + this.__destination += '/'; + } + + if (this.__subDirectories) { + this.__path = getDirs(this.__path[0]); + } } InstallDots.prototype.compileToFile = function(path, template, def) { - def = def || {}; - var modulename = path.substring(path.lastIndexOf("/")+1, path.lastIndexOf(".")) - , defs = copy(this.__includes, copy(def)) - , settings = this.__settings || doT.templateSettings - , compileoptions = copy(settings) - , defaultcompiled = doT.template(template, settings, defs) - , exports = [] - , compiled = "" - , fn; - - for (var property in defs) { - if (defs[property] !== def[property] && defs[property] !== this.__includes[property]) { - fn = undefined; - if (typeof defs[property] === 'string') { - fn = doT.template(defs[property], settings, defs); - } else if (typeof defs[property] === 'function') { - fn = defs[property]; - } else if (defs[property].arg) { - compileoptions.varname = defs[property].arg; - fn = doT.template(defs[property].text, compileoptions, defs); - } - if (fn) { - compiled += fn.toString().replace('anonymous', property); - exports.push(property); - } - } - } - compiled += defaultcompiled.toString().replace('anonymous', modulename); - fs.writeFileSync(path, "(function(){" + compiled - + "var itself=" + modulename + ", _encodeHTML=(" + doT.encodeHTMLSource.toString() + "(" + (settings.doNotSkipEncoded || '') + "));" - + addexports(exports) - + "if(typeof module!=='undefined' && module.exports) module.exports=itself;else if(typeof define==='function')define(function(){return itself;});else {" - + this.__global + "=" + this.__global + "||{};" + this.__global + "['" + modulename + "']=itself;}}());"); + def = def || {}; + var modulename = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")), + defs = copy(this.__includes, copy(def)), + settings = this.__settings || doT.templateSettings, + compileoptions = copy(settings), + defaultcompiled = doT.template(template, settings, defs), + exports = [], + compiled = "", + fn; + + for (var property in defs) { + if (defs[property] !== def[property] && defs[property] !== this.__includes[property]) { + fn = undefined; + if (typeof defs[property] === 'string') { + fn = doT.template(defs[property], settings, defs); + } else if (typeof defs[property] === 'function') { + fn = defs[property]; + } else if (defs[property].arg) { + compileoptions.varname = defs[property].arg; + fn = doT.template(defs[property].text, compileoptions, defs); + } + if (fn) { + compiled += fn.toString().replace('anonymous', property); + exports.push(property); + } + } + } + compiled += defaultcompiled.toString().replace('anonymous', modulename); + fs.writeFileSync(path, "(function(){" + compiled + "var itself=" + modulename + ", _encodeHTML=(" + doT.encodeHTMLSource.toString() + "(" + (settings.doNotSkipEncoded || '') + "));" + addexports(exports) + "if(typeof module!=='undefined' && module.exports) module.exports=itself;else if(typeof define==='function')define(function(){return itself;});else {" + this.__global + "=" + this.__global + "||{};" + this.__global + "['" + modulename + "']=itself;}}());"); +}; + +InstallDots.prototype.compilePath = function(path) { + var data = readdata(path); + if (data) { + return doT.template(data, + this.__settings || doT.templateSettings, + copy(this.__includes)); + } +}; + +// Has to be done in two loops, so .def files from subdirectories +// get discovered, before compiling the .dot and .jst files +InstallDots.prototype.compileAll = function() { + console.log("Compiling all doT templates..."); + + var k, l, name, + dirIndex, defFolder, sources, + totalTemplates = 0; + + for (dirIndex = 0; dirIndex < this.__path.length; dirIndex++) { + defFolder = this.__path[dirIndex]; + sources = fs.readdirSync(defFolder); + + for (k = 0, l = sources.length; k < l; k++) { + name = sources[k]; + + if (/\.def(\.dot|\.jst)?$/.test(name)) { + console.log("Loaded def " + name); + this.__includes[name.substring(0, name.indexOf('.'))] = readdata(defFolder + name); + totalTemplates++; + } + } + } + + for (dirIndex = 0; dirIndex < this.__path.length; dirIndex++) { + defFolder = this.__path[dirIndex]; + sources = fs.readdirSync(defFolder); + + for (k = 0, l = sources.length; k < l; k++) { + name = sources[k]; + + if (/\.dot(\.def|\.jst)?$/.test(name)) { + console.log("Compiling " + name + " to function"); + this.__rendermodule[name.substring(0, name.indexOf('.'))] = this.compilePath(defFolder + name); + totalTemplates++; + } + + if (/\.jst(\.dot|\.def)?$/.test(name)) { + console.log("Compiling " + name + " to file"); + this.compileToFile(this.__destination + name.substring(0, name.indexOf('.')) + '.js', + readdata(defFolder + name)); + totalTemplates++; + } + } + } + + console.log("Finished compiling %d templates", totalTemplates); + return this.__rendermodule; }; function addexports(exports) { - for (var ret ='', i=0; i< exports.length; i++) { - ret += "itself." + exports[i]+ "=" + exports[i]+";"; - } - return ret; + for (var ret = '', i = 0; i < exports.length; i++) { + ret += "itself." + exports[i] + "=" + exports[i] + ";"; + } + return ret; } function copy(o, to) { - to = to || {}; - for (var property in o) { - to[property] = o[property]; - } - return to; + to = to || {}; + for (var property in o) { + to[property] = o[property]; + } + return to; } function readdata(path) { - var data = fs.readFileSync(path); - if (data) return data.toString(); - console.log("problems with " + path); + var data = fs.readFileSync(path); + if (data) return data.toString(); + console.log("problems with " + path); } -InstallDots.prototype.compilePath = function(path) { - var data = readdata(path); - if (data) { - return doT.template(data, - this.__settings || doT.templateSettings, - copy(this.__includes)); - } -}; +function getDirs(dir) { + var dirs = walk(dir); -InstallDots.prototype.compileAll = function() { - console.log("Compiling all doT templates..."); - - var defFolder = this.__path, - sources = fs.readdirSync(defFolder), - k, l, name; - - for( k = 0, l = sources.length; k < l; k++) { - name = sources[k]; - if (/\.def(\.dot|\.jst)?$/.test(name)) { - console.log("Loaded def " + name); - this.__includes[name.substring(0, name.indexOf('.'))] = readdata(defFolder + name); - } - } - - for( k = 0, l = sources.length; k < l; k++) { - name = sources[k]; - if (/\.dot(\.def|\.jst)?$/.test(name)) { - console.log("Compiling " + name + " to function"); - this.__rendermodule[name.substring(0, name.indexOf('.'))] = this.compilePath(defFolder + name); - } - if (/\.jst(\.dot|\.def)?$/.test(name)) { - console.log("Compiling " + name + " to file"); - this.compileToFile(this.__destination + name.substring(0, name.indexOf('.')) + '.js', - readdata(defFolder + name)); - } - } - return this.__rendermodule; -}; + return addEndSeparator(dirs); +} + +function walk(dir) { + var results = [path.resolve(dir)], + list = fs.readdirSync(dir); + + list.forEach(function(file) { + file = path.resolve(dir, file); + var stat = fs.statSync(file); + + if (stat && stat.isDirectory()) { + results = results.concat(walk(file)); + } + }); + + return results; +} + +function addEndSeparator(dirs) { + dirs.forEach(function(element, index, array) { + array[index] = element + path.sep; + }); + + return dirs; +} From a990d05df0de64a5c81586f7b400305f89a730da Mon Sep 17 00:00:00 2001 From: Xaxatix Date: Thu, 7 May 2015 19:26:02 +0300 Subject: [PATCH 2/4] Prevent separate function generation for each ##def --- index.js | 258 +++++++++++++++++++++++++++---------------------------- 1 file changed, 129 insertions(+), 129 deletions(-) diff --git a/index.js b/index.js index e97200d..e440978 100644 --- a/index.js +++ b/index.js @@ -28,172 +28,172 @@ */ var fs = require("fs"), - path = require("path"), - doT = module.exports = require("./doT"); + path = require("path"), + doT = module.exports = require("./doT"); doT.process = function(options) { - //path, destination, global, rendermodule, templateSettings - return new InstallDots(options).compileAll(); + //path, destination, global, rendermodule, templateSettings + return new InstallDots(options).compileAll(); }; function InstallDots(o) { - this.__global = o.global || "window.render"; - this.__rendermodule = o.rendermodule || {}; - this.__settings = o.templateSettings ? copy(o.templateSettings, copy(doT.templateSettings)) : undefined; - this.__includes = {}; - this.__subDirectories = o.subDirectories || false; - this.__path = o.path ? [o.path] : ["./"]; - if (this.__path[0][this.__path[0].length - 1] !== '/') { - this.__path[0] += '/'; - } - this.__destination = o.destination || this.__path[0]; - if (this.__destination[this.__destination.length - 1] !== '/') { - this.__destination += '/'; - } - - if (this.__subDirectories) { - this.__path = getDirs(this.__path[0]); - } + this.__global = o.global || "window.render"; + this.__rendermodule = o.rendermodule || {}; + this.__settings = o.templateSettings ? copy(o.templateSettings, copy(doT.templateSettings)) : undefined; + this.__includes = {}; + this.__subDirectories = o.subDirectories || false; + this.__path = o.path ? [o.path] : ["./"]; + if (this.__path[0][this.__path[0].length - 1] !== '/') { + this.__path[0] += '/'; + } + this.__destination = o.destination || this.__path[0]; + if (this.__destination[this.__destination.length - 1] !== '/') { + this.__destination += '/'; + } + if (this.__subDirectories) { + this.__path = getDirs(this.__path[0]); + } } InstallDots.prototype.compileToFile = function(path, template, def) { - def = def || {}; - var modulename = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")), - defs = copy(this.__includes, copy(def)), - settings = this.__settings || doT.templateSettings, - compileoptions = copy(settings), - defaultcompiled = doT.template(template, settings, defs), - exports = [], - compiled = "", - fn; - - for (var property in defs) { - if (defs[property] !== def[property] && defs[property] !== this.__includes[property]) { - fn = undefined; - if (typeof defs[property] === 'string') { - fn = doT.template(defs[property], settings, defs); - } else if (typeof defs[property] === 'function') { - fn = defs[property]; - } else if (defs[property].arg) { - compileoptions.varname = defs[property].arg; - fn = doT.template(defs[property].text, compileoptions, defs); - } - if (fn) { - compiled += fn.toString().replace('anonymous', property); - exports.push(property); - } - } - } - compiled += defaultcompiled.toString().replace('anonymous', modulename); - fs.writeFileSync(path, "(function(){" + compiled + "var itself=" + modulename + ", _encodeHTML=(" + doT.encodeHTMLSource.toString() + "(" + (settings.doNotSkipEncoded || '') + "));" + addexports(exports) + "if(typeof module!=='undefined' && module.exports) module.exports=itself;else if(typeof define==='function')define(function(){return itself;});else {" + this.__global + "=" + this.__global + "||{};" + this.__global + "['" + modulename + "']=itself;}}());"); + def = def || {}; + var modulename = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")), + defs = copy(this.__includes, copy(def)), + settings = this.__settings || doT.templateSettings, + compileoptions = copy(settings), + defaultcompiled = doT.template(template, settings, defs), + exports = [], + compiled = "", + fn; + + // Prevents seperate function generation for each define + // for (var property in defs) { + // if (defs[property] !== def[property] && defs[property] !== this.__includes[property]) { + // fn = undefined; + // if (typeof defs[property] === 'string') { + // fn = doT.template(defs[property], settings, defs); + // } else if (typeof defs[property] === 'function') { + // fn = defs[property]; + // } else if (defs[property].arg) { + // compileoptions.varname = defs[property].arg; + // fn = doT.template(defs[property].text, compileoptions, defs); + // } + // if (fn) { + // compiled += fn.toString().replace('anonymous', property); + // exports.push(property); + // } + // } + // } + compiled += defaultcompiled.toString().replace('anonymous', modulename); + fs.writeFileSync(path, "(function(){" + compiled + "var itself=" + modulename + ", _encodeHTML=(" + doT.encodeHTMLSource.toString() + "(" + (settings.doNotSkipEncoded || '') + "));" + addexports(exports) + "if(typeof module!=='undefined' && module.exports) module.exports=itself;else if(typeof define==='function')define(function(){return itself;});else {" + this.__global + "=" + this.__global + "||{};" + this.__global + "['" + modulename + "']=itself;}}());"); }; InstallDots.prototype.compilePath = function(path) { - var data = readdata(path); - if (data) { - return doT.template(data, - this.__settings || doT.templateSettings, - copy(this.__includes)); - } + var data = readdata(path); + if (data) { + return doT.template(data, + this.__settings || doT.templateSettings, + copy(this.__includes)); + } }; // Has to be done in two loops, so .def files from subdirectories // get discovered, before compiling the .dot and .jst files InstallDots.prototype.compileAll = function() { - console.log("Compiling all doT templates..."); - - var k, l, name, - dirIndex, defFolder, sources, - totalTemplates = 0; - - for (dirIndex = 0; dirIndex < this.__path.length; dirIndex++) { - defFolder = this.__path[dirIndex]; - sources = fs.readdirSync(defFolder); - - for (k = 0, l = sources.length; k < l; k++) { - name = sources[k]; - - if (/\.def(\.dot|\.jst)?$/.test(name)) { - console.log("Loaded def " + name); - this.__includes[name.substring(0, name.indexOf('.'))] = readdata(defFolder + name); - totalTemplates++; - } - } - } - - for (dirIndex = 0; dirIndex < this.__path.length; dirIndex++) { - defFolder = this.__path[dirIndex]; - sources = fs.readdirSync(defFolder); - - for (k = 0, l = sources.length; k < l; k++) { - name = sources[k]; - - if (/\.dot(\.def|\.jst)?$/.test(name)) { - console.log("Compiling " + name + " to function"); - this.__rendermodule[name.substring(0, name.indexOf('.'))] = this.compilePath(defFolder + name); - totalTemplates++; - } - - if (/\.jst(\.dot|\.def)?$/.test(name)) { - console.log("Compiling " + name + " to file"); - this.compileToFile(this.__destination + name.substring(0, name.indexOf('.')) + '.js', - readdata(defFolder + name)); - totalTemplates++; - } - } - } - - console.log("Finished compiling %d templates", totalTemplates); - return this.__rendermodule; + console.log("Compiling all doT templates..."); + + var k, l, name, + dirIndex, defFolder, sources, + totalTemplates = 0; + + for (dirIndex = 0; dirIndex < this.__path.length; dirIndex++) { + defFolder = this.__path[dirIndex]; + sources = fs.readdirSync(defFolder); + + for (k = 0, l = sources.length; k < l; k++) { + name = sources[k]; + + if (/\.def(\.dot|\.jst)?$/.test(name)) { + console.log("Loaded def " + name); + this.__includes[name.substring(0, name.indexOf('.'))] = readdata(defFolder + name); + totalTemplates++; + } + } + } + + for (dirIndex = 0; dirIndex < this.__path.length; dirIndex++) { + defFolder = this.__path[dirIndex]; + sources = fs.readdirSync(defFolder); + + for (k = 0, l = sources.length; k < l; k++) { + name = sources[k]; + + if (/\.dot(\.def|\.jst)?$/.test(name)) { + console.log("Compiling " + name + " to function"); + this.__rendermodule[name.substring(0, name.indexOf('.'))] = this.compilePath(defFolder + name); + totalTemplates++; + } + + if (/\.jst(\.dot|\.def)?$/.test(name)) { + console.log("Compiling " + name + " to file"); + this.compileToFile(this.__destination + name.substring(0, name.indexOf('.')) + '.js', + readdata(defFolder + name)); + totalTemplates++; + } + } + } + + console.log("Finished compiling %d templates", totalTemplates); + return this.__rendermodule; }; function addexports(exports) { - for (var ret = '', i = 0; i < exports.length; i++) { - ret += "itself." + exports[i] + "=" + exports[i] + ";"; - } - return ret; + for (var ret = '', i = 0; i < exports.length; i++) { + ret += "itself." + exports[i] + "=" + exports[i] + ";"; + } + return ret; } function copy(o, to) { - to = to || {}; - for (var property in o) { - to[property] = o[property]; - } - return to; + to = to || {}; + for (var property in o) { + to[property] = o[property]; + } + return to; } function readdata(path) { - var data = fs.readFileSync(path); - if (data) return data.toString(); - console.log("problems with " + path); + var data = fs.readFileSync(path); + if (data) return data.toString(); + console.log("problems with " + path); } function getDirs(dir) { - var dirs = walk(dir); + var dirs = walk(dir); - return addEndSeparator(dirs); + return addEndSeparator(dirs); } function walk(dir) { - var results = [path.resolve(dir)], - list = fs.readdirSync(dir); + var results = [path.resolve(dir)], + list = fs.readdirSync(dir); - list.forEach(function(file) { - file = path.resolve(dir, file); - var stat = fs.statSync(file); + list.forEach(function(file) { + file = path.resolve(dir, file); + var stat = fs.statSync(file); - if (stat && stat.isDirectory()) { - results = results.concat(walk(file)); - } - }); + if (stat && stat.isDirectory()) { + results = results.concat(walk(file)); + } + }); - return results; + return results; } function addEndSeparator(dirs) { - dirs.forEach(function(element, index, array) { - array[index] = element + path.sep; - }); + dirs.forEach(function(element, index, array) { + array[index] = element + path.sep; + }); - return dirs; + return dirs; } From 45daaa578f9b12732a8e78938f5890366a6ca710 Mon Sep 17 00:00:00 2001 From: Xaxatix Date: Sat, 9 May 2015 17:02:41 +0300 Subject: [PATCH 3/4] Bumped up version number --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 95af955..a72729b 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "simple", "templating" ], - "version": "1.0.3", + "version": "1.1.3", "main": "index", "bin": { "dottojs": "./bin/dot-packer" From 32dfabb40cf82397dbe67527bcbc5838ff5805f5 Mon Sep 17 00:00:00 2001 From: Xaxatix Date: Sat, 9 May 2015 19:55:49 +0300 Subject: [PATCH 4/4] Initialization of the local variable when compiling --- doT.js | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doT.js b/doT.js index 86ffc2e..e2857b8 100644 --- a/doT.js +++ b/doT.js @@ -6,7 +6,7 @@ "use strict"; var doT = { - version: "1.0.3", + version: "1.1.4", templateSettings: { evaluate: /\{\{([\s\S]+?(\}?)+)\}\}/g, interpolate: /\{\{=([\s\S]+?)\}\}/g, @@ -91,7 +91,7 @@ var cse = c.append ? startend.append : startend.split, needhtmlencode, sid = 0, indv, str = (c.use || c.define) ? resolveDefs(c, tmpl, def || {}) : tmpl; - str = ("var out='" + (c.strip ? str.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ") + str = (c.varname + "=" + c.varname + "||{};" + "var out='" + (c.strip ? str.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ") .replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""): str) .replace(/'|\\/g, "\\$&") .replace(c.interpolate || skip, function(m, code) { diff --git a/package.json b/package.json index a72729b..1efb98d 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "simple", "templating" ], - "version": "1.1.3", + "version": "1.1.4", "main": "index", "bin": { "dottojs": "./bin/dot-packer"