UNPKG

4.92 kBJavaScriptView Raw
1var jade = require('jade');
2var beautify = require('./lib/beautify');
3var simplifyTemplate = require('./lib/simplifyTemplate');
4var transformMixins = require('./lib/transformMixins');
5var renameJadeFn = require('./lib/renameJadeFn');
6var walkdir = require('walkdir');
7var path = require('path');
8var _ = require('underscore');
9var fs = require('fs');
10var uglifyjs = require('uglify-js');
11var namedTemplateFn = require('./lib/namedTemplateFn');
12var bracketedName = require('./lib/bracketedName');
13
14
15module.exports = function (templateDirectories, outputFile, options) {
16 options || (options = {});
17
18 _.defaults(options, {
19 dontTransformMixins: false,
20 jade: {}
21 });
22
23 if (typeof templateDirectories === "string") {
24 templateDirectories = [templateDirectories];
25 }
26 var rootName = 'templatizer';
27 var folders = [];
28 var templates = [];
29 var _readTemplates = [];
30 var isWindows = process.platform === 'win32';
31 var pathSep = path.sep || (isWindows ? '\\' : '/');
32 var pathSepRegExp = /\/|\\/g;
33
34 // Find jade runtime and create minified code
35 // where it is assigned to the variable jade
36 var placesToLook = [
37 __dirname + '/node_modules/jade/lib/runtime.js',
38 __dirname + '/jaderuntime.js'
39 ];
40 var jadeRuntime = fs.readFileSync(_.find(placesToLook, fs.existsSync)).toString();
41 var wrappedJade = uglifyjs.minify('var jade = (function(){var exports={};' + jadeRuntime + 'return exports;})();', {fromString: true}).code;
42
43 var outputTemplate = fs.readFileSync(__dirname + '/output_template.js').toString();
44 var output = '';
45
46 var jadeCompileOptions = {
47 client: true,
48 compileDebug: false,
49 pretty: false
50 };
51 _.extend(jadeCompileOptions, options.jade);
52
53 templateDirectories = _.map(templateDirectories, function (templateDirectory) {
54 return templateDirectory.replace(pathSepRegExp, pathSep);
55 });
56
57 templateDirectories.forEach(function (templateDirectory) {
58 if (!fs.existsSync(templateDirectory)) {
59 throw new Error('Template directory ' + templateDirectory + ' does not exist.');
60 }
61
62 walkdir.sync(templateDirectory).forEach(function (file) {
63 var item = file.replace(path.resolve(templateDirectory), '').slice(1);
64 if (path.extname(item) === '' && path.basename(item).charAt(0) !== '.') {
65 if (folders.indexOf(item) === -1) folders.push(item);
66 } else if (path.extname(item) === '.jade') {
67 // Throw an err if we are about to override a template
68 if (_readTemplates.indexOf(item) > -1) {
69 throw new Error(item + ' from ' + templateDirectory + pathSep + item + ' already exists in ' + templates[_readTemplates.indexOf(item)]);
70 }
71 _readTemplates.push(item);
72 templates.push(templateDirectory + pathSep + item);
73 }
74 });
75
76 folders = _.sortBy(folders, function (folder) {
77 var arr = folder.split(pathSep);
78 return arr.length;
79 });
80 });
81
82 output += folders.map(function (folder) {
83 return rootName + bracketedName(folder.split(pathSep)) + ' = {};';
84 }).join('\n') + '\n';
85
86 templates.forEach(function (item) {
87 var name = path.basename(item, '.jade');
88 var dirString = function () {
89 var itemTemplateDir = _.find(templateDirectories, function (templateDirectory) {
90 return item.indexOf(templateDirectory + pathSep) === 0;
91 });
92 var dirname = path.dirname(item).replace(itemTemplateDir, '');
93 if (dirname === '.') return name;
94 dirname += '.' + name;
95 return dirname.substring(1).replace(pathSepRegExp, '.');
96 }();
97
98 jadeCompileOptions.filename = item;
99 var template = beautify(jade.compileClient(fs.readFileSync(item, 'utf-8'), jadeCompileOptions).toString());
100
101 template = renameJadeFn(template, dirString);
102 template = simplifyTemplate(template);
103
104 var mixins = [];
105 if (!options.dontTransformMixins) {
106 var astResult = transformMixins({
107 template: template,
108 name: name,
109 dir: dirString,
110 rootName: rootName
111 });
112 mixins = astResult.mixins;
113 template = astResult.template;
114 }
115
116 output += namedTemplateFn({
117 dir: dirString,
118 rootName: rootName,
119 fn: template
120 });
121
122 output += mixins.join('\n');
123 });
124
125 var indentOutput = output.split('\n').map(function (l) { return l ? ' ' + l : l; }).join('\n');
126 var finalOutput = outputTemplate
127 .replace('{{jade}}', wrappedJade)
128 .replace('{{code}}', indentOutput);
129
130 if (outputFile) fs.writeFileSync(outputFile, finalOutput);
131
132 return finalOutput;
133};