Skip to content

Commit 28f744e

Browse files
unknownunknown
unknown
authored and
unknown
committed
First release
1 parent 11c42d4 commit 28f744e

File tree

5 files changed

+433
-0
lines changed

5 files changed

+433
-0
lines changed

package.json

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"author": "Mike Coolin <[email protected]> (www.coolwebdevelopment.ca)",
3+
"name": "Node-JavaScript-Preprocessor",
4+
"description": "A preprocessor for Javascript that supports defines, if else endif and includes.",
5+
"version": "0.0.1",
6+
"homepage": "http://coolwebdevelopment.ca/wordpress/index.php/developers-area/javascript/node-javascript-preprocessor/",
7+
"repository": {
8+
"type": "git",
9+
"url": "git://github.com/mcoolin/Node-JavaScript-Preprocessor.git"
10+
},
11+
"main": "pp.js",
12+
"scripts": {
13+
"test": "node pp.js --help"
14+
},
15+
"engines": {
16+
"node": "~v0.4.11"
17+
},
18+
"dependencies": {},
19+
"devDependencies": {}
20+
}

pp.js

+328
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
/*
2+
3+
pp a javascript preprocessor
4+
5+
Copyright (c) 2010 Mike Coolin
6+
7+
Permission is hereby granted, free of charge, to any person
8+
obtaining a copy of this software and associated documentation
9+
files (the "Software"), to deal in the Software without
10+
restriction, including without limitation the rights to use,
11+
copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
copies of the Software, and to permit persons to whom the
13+
Software is furnished to do so, subject to the following
14+
conditions:
15+
16+
The above copyright notice and this permission notice shall be
17+
included in all copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26+
OTHER DEALINGS IN THE SOFTWARE.
27+
*/
28+
29+
var fs = require('fs'),
30+
files = [],
31+
opts = require('tav').set({
32+
src: {
33+
note: 'Source file(s) e.g. --src=file1.js,file2.js'
34+
},
35+
dst: {
36+
note: 'Destination to write the file e.g. --dst=o.js'
37+
},
38+
def: {
39+
note: 'Defintion(s) to create e.g. --def=DEBUG,NODE,BROWSER',
40+
value: ''
41+
},
42+
debug : {
43+
note : 'Enable debugging',
44+
value : false
45+
}
46+
}, "Usage: node pp.js with the following options");
47+
48+
doPreprocess(opts);
49+
50+
function doPreprocess(opts){
51+
if(debug){
52+
console.log(opts);
53+
}
54+
var sa,
55+
writestream = fs.createWriteStream(opts.dst,
56+
{ flags: 'w',
57+
encoding: 'utf8',
58+
mode: 0666
59+
}),
60+
debug = opts.debug,
61+
defines = [],
62+
pplines=[],
63+
comment = '// ',
64+
commentCode='',
65+
cnt;
66+
67+
// handle defines
68+
sa=opts.def.split(',');
69+
for(cnt=0;cnt<sa.length;cnt++){
70+
defines.push(sa[cnt]);
71+
log('Passed in define '+sa[cnt]);
72+
}
73+
74+
sa=opts.src.split(',');
75+
for(cnt=0;cnt<sa.length;cnt++){
76+
loadFileandAddLineObject(sa[cnt],pplines);
77+
}
78+
79+
ifPass(pplines, defines);
80+
81+
if(debug){
82+
dumpLineObjarr(pplines);
83+
}
84+
85+
for(cnt=0;cnt<pplines.length;cnt++){
86+
if(pplines[cnt].addComment){
87+
commentCode=comment;
88+
} else {
89+
commentCode='';
90+
}
91+
writestream.write(commentCode + pplines[cnt].text + '\n', 'utf8');
92+
}
93+
94+
writestream.end('');
95+
}
96+
97+
function parseIf(str){
98+
return trim(str.replace(/^\s*\/\/@if\b/,''));
99+
}
100+
101+
function parseInclude(str){
102+
return trim(str.replace(/^\s*\/\/@include\b/,''));
103+
}
104+
105+
function parseDefine(str){
106+
return trim(str.replace(/^\s*\/\/@define\b/,''));
107+
}
108+
109+
function trim(str){
110+
return str.replace(/^\s\s*/, '')
111+
.replace(/\s\s*$/, '');
112+
}
113+
114+
function include(arr,obj) {
115+
return (arr.indexOf(obj) != -1);
116+
}
117+
118+
// Add file to process
119+
// write a header and footer line of file that is being processed
120+
// append file to file list
121+
function addFile(fileName) {
122+
// add logic to detect infinite loops
123+
if(include(files,fileName)){
124+
throw new Error('file '+fileName+' has already been included');
125+
}
126+
files.push(fileName);
127+
}
128+
129+
// produce a string of x characters
130+
function repeat(str, num) {
131+
var cnt, rv='';
132+
133+
for (cnt = 0; cnt < num; cnt++) {
134+
rv += str;
135+
}
136+
return rv;
137+
}
138+
139+
// loadFileandAddLineObject
140+
function loadFileandAddLineObject(fileName,arr){
141+
var cnt, temparr=[],
142+
textheader, textfooter,
143+
headerlen = Math.round((80 - (fileName.length + 5)) / 2),
144+
footerlen = Math.round((80 - (fileName.length + 9)) / 2);
145+
146+
temparr = fs.readFileSync(fileName, 'utf8').split('\n');
147+
148+
// add a header and footer to the array for the file
149+
textheader = '// ' + repeat("-", headerlen) + ' ' + fileName + ' ' + repeat("-", headerlen);
150+
// log(textheader);
151+
textfooter = '// ' + repeat("-", footerlen) + ' end ' + fileName + ' ' + repeat("-", footerlen);
152+
// log(textfooter)
153+
temparr.unshift(textheader);
154+
temparr.push(textfooter);
155+
156+
for(cnt=0;cnt<temparr.length;cnt++){
157+
arr.push(new lineObj(temparr[cnt]));
158+
}
159+
}
160+
161+
// dumplineObj
162+
function dumpLineObjarr(arr){
163+
var cnt;
164+
165+
for(cnt=0;cnt<arr.length;cnt++){
166+
log(cnt+' ac('+arr[cnt].addComment+') vl('+arr[cnt].ifval+')\t'+arr[cnt].text)
167+
}
168+
}
169+
170+
// loop through lines and locate the if/endif blocks
171+
function ifPass(arr,defines){
172+
var startEndStack = [],
173+
iv=false,
174+
dopop=false,
175+
pv, pa, pc,
176+
ifpattern=/^\s*\/\/@if\b/g,
177+
includepattern=/^\s*\/\/@include\b/g,
178+
elsepattern=/^\s*\/\/@else/g,
179+
definepattern = /^\s*\/\/@define\b/g,
180+
endifpattern = /^\s*\/\/@endif/g;
181+
182+
for(cnt=0;cnt<arr.length;cnt++){
183+
if(!arr[cnt].addcomment){
184+
//define processing
185+
if (definepattern.test(arr[cnt].text)) {
186+
// get the parameter(s) and add then to the defines list
187+
//(assuming a csv list)
188+
pv = parseDefine(arr[cnt].text);
189+
log('parsedefine returned (' + pv + ')');
190+
191+
pa = pv.split(',');
192+
for (pc = 0; pc < pa.length; pc++) {
193+
log('adding ' + pa[pc] + ' to defines');
194+
defines.push(pa[pc]);
195+
}
196+
arr[cnt].addComment=true;
197+
}
198+
199+
// include processing
200+
if (includepattern.test(arr[cnt].text)) {
201+
pv = parseInclude(arr[cnt].text);
202+
arr[cnt].addComment=true;
203+
204+
addFile(pv);
205+
if(arr[cnt].ifval!==false){
206+
if(startEndStack.length>0 ){
207+
if(startEndStack[(startEndStack.length-1)].iv){
208+
loadFileandPrepend(pv, arr, cnt+1);
209+
}
210+
}
211+
}
212+
}
213+
214+
//if else endif
215+
if(ifpattern.test(arr[cnt].text)){
216+
pv = parseIf(arr[cnt].text);
217+
pa = pv.split(',');
218+
iv=false;
219+
for (pc = 0; pc < pa.length; pc++) {
220+
if (include(defines, pa[pc])) {
221+
iv = true;
222+
}
223+
}
224+
arr[cnt].addComment=true;
225+
arr[cnt].ifval=iv;
226+
if(startEndStack.length==1){
227+
//arr[cnt].ifval=iv;
228+
} else {
229+
if(startEndStack.length>0){
230+
iv=arr[cnt].addComment=startEndStack[0].iv;
231+
}
232+
}
233+
startEndStack.push(new ifobj(iv));
234+
} else {
235+
if(endifpattern.test(arr[cnt].text)){
236+
arr[cnt].addComment=true;
237+
if(startEndStack.length>0){
238+
dopop=true;
239+
}
240+
} else {
241+
if(elsepattern.test(arr[cnt].text)){
242+
if(startEndStack.length>0 ){
243+
log('cnt='+cnt+' elselength='+startEndStack.length);
244+
if(startEndStack[0].iv){
245+
startEndStack[(startEndStack.length-1)].iv= (!startEndStack[(startEndStack.length-1)].iv);
246+
arr[cnt].addcomment=startEndStack[0].iv;
247+
}
248+
}
249+
arr[cnt].addComment=true;
250+
}
251+
}
252+
}
253+
254+
if(!arr[cnt].addComment){
255+
// log(cnt);
256+
if(startEndStack.length>0){
257+
arr[cnt].ifval=startEndStack[(startEndStack.length-1)].iv;
258+
if(arr[cnt].ifval==false){
259+
arr[cnt].addComment=true;
260+
}
261+
}
262+
}
263+
264+
// do line settings
265+
if(startEndStack>0){
266+
// arr[cnt].addComment=startEndStack[startEndStack.length-1].iv;
267+
}
268+
// log('cnt='+cnt+' '+startEndStack.length)
269+
if(dopop){
270+
startEndStack.pop();
271+
dopop=false;
272+
}
273+
}
274+
}
275+
}
276+
277+
// load a file and prepend it to an array
278+
function loadFileandPrepend(fileName, arr, at) {
279+
var cnt,
280+
textheader, textfooter,
281+
headerlen = Math.round((80 - (fileName.length + 5)) / 2),
282+
footerlen = Math.round((80 - (fileName.length + 9)) / 2),
283+
temparr = [];
284+
285+
temparr = fs.readFileSync(fileName, 'utf8').split('\n');
286+
287+
// add a header and footer to the array for the file
288+
textheader = '// ' + repeat("-", headerlen) + ' ' + fileName + ' ' + repeat("-", headerlen);
289+
// log(textheader);
290+
textfooter = '// ' + repeat("-", footerlen) + ' end ' + fileName + ' ' + repeat("-", footerlen);
291+
// log(textfooter)
292+
temparr.unshift(textheader);
293+
temparr.push(textfooter);
294+
295+
// loop through the array and insert the items to arr
296+
for (cnt=0; cnt<temparr.length; cnt++) {
297+
log('adding '+temparr[cnt]+' from '+fileName)
298+
arr.splice(at+cnt,0, new lineObj(temparr[cnt]));
299+
}
300+
}
301+
302+
function log(str) {
303+
if (!opts.debug) {
304+
return;
305+
}
306+
console.log(str);
307+
}
308+
309+
function lineObj(line){
310+
this.addComment=false;
311+
this.ifvars='';
312+
this.ifval=null;
313+
this.text=line;
314+
}
315+
316+
function dumpobj(obj){
317+
var n;
318+
for(n in obj){
319+
log(n+'='+obj[n]);
320+
}
321+
}
322+
323+
function ifobj(iv){
324+
this.iv=iv;
325+
}
326+
327+
328+

tests/ifendif.js

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* a simple test of the if endif logic
3+
*
4+
*/
5+
//@define Hello
6+
7+
//@if Hello
8+
This should show
9+
//@else
10+
This should be commented
11+
//@endif
12+
13+
//@include nestedfile3.js
14+
15+
//@if DEBUG
16+
This should be commented
17+
//@else
18+
This should show
19+
//@endif
20+
21+
//@if DEBUG
22+
//@if WIRE
23+
This should be commented
24+
//@else
25+
This should be commented (because its nested out)
26+
//@endif
27+
//@else
28+
This should show
29+
//@endif
30+
31+
//@if DEBUG
32+
This should be commented
33+
//@endif
34+
//@if DEBUG
35+
//@include nofile.js this should not show
36+
//@endif
37+
//@if Hello,DEBUG
38+
This should show
39+
//@endif

tests/nestedfile3.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
This is the nested file 3
2+
3+
//@if Hello
4+
This should show
5+
//@endif

0 commit comments

Comments
 (0)