1 | CoffeeScript = require 'coffee-script'
|
2 | CoffeeMaker = require './coffee-maker'
|
3 | fs = require 'fs'
|
4 | findit = require 'findit'
|
5 |
|
6 | red = '\u001b[31m'
|
7 | green = '\u001b[32m'
|
8 | reset = '\u001b[0m'
|
9 |
|
10 | optimist = require('optimist')
|
11 | .usage('Usage: $0')
|
12 | .options('i',
|
13 | alias : 'input'
|
14 | describe : 'Either a file or a directory name to be compiled'
|
15 | )
|
16 | .options('o',
|
17 | alias : 'output'
|
18 | describe : 'Set the output filename'
|
19 | )
|
20 | .options('n',
|
21 | alias : 'namespace'
|
22 | describe : 'Set a custom template namespace'
|
23 | default : 'window.HAML'
|
24 | )
|
25 | .options('t',
|
26 | alias : 'template'
|
27 | describe : 'Set a custom template name'
|
28 | )
|
29 | .options('b',
|
30 | alias : 'basename'
|
31 | boolean : true
|
32 | default : false
|
33 | describe : 'Ignore file path when generate the template name'
|
34 | )
|
35 | .options('f',
|
36 | alias : 'format'
|
37 | default : 'html5'
|
38 | describe : 'Set HTML output format, either `xhtml`, `html4` or `html5`'
|
39 | )
|
40 | .options('u',
|
41 | alias : 'uglify'
|
42 | boolean : true
|
43 | default : false
|
44 | describe : 'Do not properly indent or format the HTML output'
|
45 | )
|
46 | .options('e',
|
47 | alias : 'extend'
|
48 | boolean : true
|
49 | default : false
|
50 | describe : 'Extend the template scope with the context'
|
51 | )
|
52 | .options('p',
|
53 | alias : 'placement'
|
54 | default : 'global'
|
55 | describe : 'Where to place the template function; one of: global, amd'
|
56 | )
|
57 | .options('d',
|
58 | alias : 'dependencies'
|
59 | default : "{ hc: 'hamlcoffee' }"
|
60 | describe : 'The global template amd module dependencies'
|
61 | )
|
62 | .options('preserve',
|
63 | default : 'pre,textarea'
|
64 | describe : 'Set a comma separated list of HTML tags to preserve'
|
65 | )
|
66 | .options('autoclose',
|
67 | default : 'meta,img,link,br,hr,input,area,param,col,base'
|
68 | describe : 'Set a comma separated list of self-closed HTML tags'
|
69 | )
|
70 | .options('hyphenate-data-attrs',
|
71 | boolean : true
|
72 | describe : 'Convert underscores to hyphens for data attribute keys'
|
73 | )
|
74 | .options('disable-html-attribute-escaping',
|
75 | boolean : true
|
76 | default : true
|
77 | describe : 'Disable any HTML attribute escaping'
|
78 | )
|
79 | .options('disable-html-escaping',
|
80 | boolean : true
|
81 | describe : 'Disable any HTML escaping'
|
82 | )
|
83 | .options('disable-clean-value',
|
84 | boolean : true
|
85 | describe : 'Disable any CoffeeScript code value cleaning'
|
86 | )
|
87 | .options('custom-html-escape',
|
88 | default : ''
|
89 | describe : 'Set the custom HTML escaping function name'
|
90 | )
|
91 | .options('custom-preserve',
|
92 | default : ''
|
93 | describe : 'Set the custom preserve whitespace function name'
|
94 | )
|
95 | .options('custom-find-and-preserve',
|
96 | default : ''
|
97 | describe : 'Set the custom find and preserve whitespace function name'
|
98 | )
|
99 | .options('custom-clean-value',
|
100 | default : ''
|
101 | describe : 'Set the custom code value clean function name'
|
102 | )
|
103 | .options('custom-surround',
|
104 | default : ''
|
105 | describe : 'Set the custom surround function name'
|
106 | )
|
107 | .options('custom-succeed',
|
108 | default : ''
|
109 | describe : 'Set the custom succeed function name'
|
110 | )
|
111 | .options('custom-precede',
|
112 | default : ''
|
113 | describe : 'Set the custom precede function name'
|
114 | )
|
115 | .options('custom-reference',
|
116 | default : ''
|
117 | describe : 'Set the custom object reference function name'
|
118 | )
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 | exports.run = ->
|
125 | argv = optimist.argv
|
126 |
|
127 | throw new Error("Unknown template format '#{ argv.f }'") if ['xhtml', 'html4', 'html5'].indexOf(argv.f) is -1
|
128 |
|
129 | inputFilename = argv.i
|
130 | templateName = argv.t
|
131 | namespace = argv.n
|
132 | dependencies = {}
|
133 |
|
134 | try
|
135 | dependencies = CoffeeScript.eval(argv.d)
|
136 | catch err
|
137 | console.error " #{ red }[Haml Coffee] Invalid dependencies:#{ reset } %s (%s)", argv.d, err
|
138 |
|
139 | compilerOptions =
|
140 | placement : argv.p
|
141 | dependencies : dependencies
|
142 | format : argv.f
|
143 | uglify : argv.u
|
144 | extendScope : argv.e
|
145 | preserveTags : argv.preserve
|
146 | escapeHtml : not argv['disable-html-escaping']
|
147 | escapeAttributes : not argv['disable-html-attribute-escaping']
|
148 | cleanValue : not argv['disable-clean-value']
|
149 | hyphenateDataAttrs : argv['hyphenate-data-attrs']
|
150 | customHtmlEscape : argv['custom-html-escape']
|
151 | customCleanValue : argv['custom-clean-value']
|
152 | customFindAndPreserve : argv['custom-find-and-preserve']
|
153 | customPreserve : argv['custom-preserve']
|
154 | customSurround : argv['custom-surround']
|
155 | customSucceed : argv['custom-succeed']
|
156 | customPrecede : argv['custom-precede']
|
157 | customReference : argv['custom-reference']
|
158 | basename : argv['basename']
|
159 |
|
160 | if inputFilename
|
161 | fs.stat inputFilename, (err, stat) ->
|
162 | unless err
|
163 |
|
164 |
|
165 | unless stat.isDirectory()
|
166 | outputFilename = argv.o || "#{ argv.i.match(/([^\.]+)(\.html)?\.haml[c]?$/)?[1] }.jst"
|
167 | console.error " #{ green }[Haml Coffee] Compiling file#{ reset } %s to %s", inputFilename, outputFilename
|
168 | fs.writeFileSync outputFilename, CoffeeMaker.compileFile(inputFilename, compilerOptions, namespace, templateName)
|
169 |
|
170 | process.exit 0
|
171 |
|
172 |
|
173 | else
|
174 | if templateName
|
175 | console.error " #{ red }[Haml Coffee] You can\'t compile all Haml templates in a directory and give a single template name!#{ reset }"
|
176 | process.exit 1
|
177 |
|
178 | console.log " #{ green }[Haml Coffee] Compiling directory#{ reset } %s", inputFilename
|
179 |
|
180 |
|
181 | baseDir = inputFilename.replace(/\/$/, '')
|
182 |
|
183 |
|
184 | compound = ''
|
185 |
|
186 |
|
187 | for filename in findit.sync baseDir
|
188 | if filename.match /([^\.]+)(\.html)?\.haml[c]?$/
|
189 |
|
190 |
|
191 | if argv.o
|
192 | console.log " #{ green }[Haml Coffee] Compiling file#{ reset } %s", filename
|
193 | compound += CoffeeMaker.compileFile(filename, compilerOptions, namespace)
|
194 |
|
195 |
|
196 | else
|
197 | outputFilename = "#{ filename.match(/([^\.]+)(\.html)?\.haml[c]?$/)?[1] }.jst"
|
198 | console.log " #{ green }[Haml Coffee] Compiling file#{ reset } %s to %s", inputFilename, outputFilename
|
199 | fs.writeFileSync outputFilename, CoffeeMaker.compileFile(filename, compilerOptions)
|
200 |
|
201 |
|
202 | if argv.o
|
203 | console.log " #{ green }[Haml Coffee] Writing all templates to#{ reset } %s", argv.o
|
204 | fs.writeFileSync argv.o, compound
|
205 |
|
206 | process.exit 0
|
207 |
|
208 | else
|
209 | console.error " #{ red }[Haml Coffee] Error compiling file#{ reset } %s: %s", argv.i, err
|
210 | process.exit 1
|
211 |
|
212 | else if argv.help
|
213 | console.log optimist.help()
|
214 |
|
215 |
|
216 | else
|
217 | if require('tty').isatty(process.stdin)
|
218 | console.log 'Please enter template source code and press Ctrl-D to generate:\n'
|
219 |
|
220 | source = ''
|
221 | process.stdin.resume()
|
222 | process.stdin.setEncoding 'utf8'
|
223 | process.stdin.on 'data', (chunk) -> source += chunk
|
224 | process.stdin.on 'end', ->
|
225 | console.log '\n'
|
226 | process.stdout.write CoffeeMaker.compile(source, (templateName || 'test'), namespace, compilerOptions)
|