1 | var jade = require('jade');
|
2 | var beautify = require('./lib/beautify');
|
3 | var simplifyTemplate = require('./lib/simplifyTemplate');
|
4 | var transformMixins = require('./lib/transformMixins');
|
5 | var renameJadeFn = require('./lib/renameJadeFn');
|
6 | var walkdir = require('walkdir');
|
7 | var path = require('path');
|
8 | var _ = require('underscore');
|
9 | var fs = require('fs');
|
10 | var uglifyjs = require('uglify-js');
|
11 | var namedTemplateFn = require('./lib/namedTemplateFn');
|
12 | var bracketedName = require('./lib/bracketedName');
|
13 |
|
14 |
|
15 | module.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 |
|
35 |
|
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 |
|
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 | };
|