Skip to content

Instantly share code, notes, and snippets.

@Zirak
Created March 8, 2012 11:47
Show Gist options
  • Select an option

  • Save Zirak/2000648 to your computer and use it in GitHub Desktop.

Select an option

Save Zirak/2000648 to your computer and use it in GitHub Desktop.
C's #include
//looks for comments at the beginning of a line looking like this:
//#build fileName
//and replaces them with fileName contents
//throws an error when fileName points to a file which doesn't exist
//first parameter is the file on which to operate,
//second parameter is a function which is called at the of operation with the
// new content
//no changes are done to the original file
var fs = require( 'fs' ),
path = require( 'path' );
var build = exports.build = function ( filePath, cb ) {
var lastIndex = 0, index,
source,
instruction = '//#build ';
fs.readFile( filePath, 'utf8', function ( err, data ) {
if ( err ) {
throw err;
}
source = data;
preprocess(function cont () {
//this is the continuation function, which is called when either
// the processor finished doing its job, or if the processor
// skipped a match for any reason.
// it sets the index for the next match to begin with, and
// calls the preprocess function again. recursion ftw
lastIndex = index + instruction.length;
preprocess( cont );
});
});
function preprocess ( next ) {
index = source.indexOf( instruction, lastIndex );
if ( index < 0 ) {
finish();
return;
}
//check to see if you're at the beginning of a line or at the beginning
// of the file
var offset, targetName = '';
if ( index === 0 || source[index-1] === '\n' ) {
offset = index + instruction.length;
//capture the filename:
//#build blah.js
// [-----] <-- this part, everything until a newline or EOF
while (
source[offset] &&
source[offset] !== '\n' && source[offset] !== '\r'
) {
targetName += source[ offset++ ];
}
//check to see if the file requested exists
path.exists( targetName, function ( exists ) {
if ( !exists ) {
throw new Error(
'Cannot #build unexisting file ' + targetName +
' (in ' + filePath + ')'
);
}
embedFile( targetName );
});
}
else {
next();
}
function embedFile ( targetName ) {
fs.readFile( targetName, 'utf8', function ( err, data ) {
if ( err ) {
throw err;
}
//replace the comment with the file content
//TODO: make this better
//this seems INCREDIBLY inefficient, and should be replaced with
// some better solution
source =
source.slice( 0, index ) +
data +
source.slice(
index + instruction.length + targetName.length
);
next();
});
}
}
function finish () {
cb( source );
}
};
//if we were executed directly,
if ( module === require.main ) {
var inpName = process.argv[ 2 ] || 'test.js',
outName = process.argv[ 3 ] || 'result.js';
build( inpName, function ( data ) {
fs.writeFile( outName, data, 'utf8', function ( err ) {
if ( err ) {
throw err;
}
console.log( 'complete' );
});
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment