Skip to content

Commit

Permalink
initial commit, pulled from grunt-preprocess
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarrod Overson committed Nov 2, 2012
0 parents commit 1e3a576
Show file tree
Hide file tree
Showing 18 changed files with 1,005 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea
node_modules

1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/node_modules/
49 changes: 49 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use strict';

module.exports = function(grunt) {

// Project configuration.
grunt.initConfig({
test: {
files: ['test/**/*_test.js']
},
lint: {
files: ['Gruntfile.js', 'tasks/**/*.js', '<config:test.files>']
},
watch: {
files: '<config:lint.files>',
tasks: 'default'
},
preprocess : {
html : {
src : 'test/test.html',
dest : 'test/test.processed.html'
},
js : {
src : 'test/test.js',
dest : 'test/test.processed.js'
}
},
jshint: {
options: {
curly: true,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
undef: true,
boss: true,
eqnull: true,
node: true,
es5: true
},
globals: {}
}
});

// Default task.
grunt.registerTask('default', 'test');

};
13 changes: 13 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright 2012 OneHealth Solutions, Inc

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
180 changes: 180 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# preprocess

Preprocess HTML, JavaScript, and other files with directives based off custom or ENV configuration

## What does it look like?

```html
<head>
<title>Your App

<!-- @if NODE_ENV='production' -->
<script src="some/production/lib/like/analytics.js"></script>
<!-- @endif -->

</head>
<body>
<!-- @ifdef DEBUG -->
<h1>Debugging mode - <!-- @echo RELEASE_TAG --> </h1>
<!-- @endif -->
<p>
<!-- @include welcome_message.txt -->
</p>
</body>
```

```js
var configValue = '/* @echo FOO */' || 'default value';

// @ifdef DEBUG
someDebuggingCall()
// @endif

```

## Directive syntax

### Simple syntax

The most basic usage is for files that only have two states, non-processed and processed.
In this case, your directives for exclude are removed after the `preprocess` task

```html
<body>
<!-- @exclude -->
<header>You're on dev!</header>
<!-- @endexclude -->
</body>
```

After build

```html
<body>
</body>
```

### Advanced directives

- `@if VAR='value'` / `@endif`
This will include the enclosed block if your test passes
- `@ifdef VAR` / `@endif`
This will include the enclosed block if VAR is defined (typeof !== 'undefined')
- `@ifndef VAR` / `@endif`
This will include the enclosed block if VAR is not defined (typeof === 'undefined')
- `@include`
This will include the source from an external file
- `@exclude` / `@endexclude`
This will remove the enclosed block upon processing
- `@echo VAR`
This will include the environment variable VAR into your source

### Extended html Syntax

This is useful for more fine grained control of your files over multiple
environment configurations. You have access to simple tests of any ENV variable

```html
<body>
<!-- @if NODE_ENV!='production' -->
<header>Your on dev!</header>
<!-- @endif -->

<!-- @if NODE_ENV='production' -->
<script src="some/production/javascript.js"></script>
<!-- @endif -->

<script>
var fingerprint = '<!-- @echo COMMIT_HASH -->' || 'DEFAULT';
</script>
</body>
```

With a `NODE_ENV` set to `production` and `0xDEADBEEF` in
`COMMIT_HASH` this will be built to look like

```html
<body>
<script src="some/production/javascript.js"></script>

<script>
var fingerprint = '0xDEADBEEF' || 'DEFAULT';
</script>
</body>
```

With NODE_ENV not set or set to dev and nothing in COMMIT_HASH,
the built file will be

```html
<body>
<header>Your on dev!</header>

<script>
var fingerprint = '' || 'DEFAULT';
</script>
</body>
```


### JavaScript Syntax

Extended syntax below, but will work without specifying a test

```js
normalFunction();
//@exclude
superExpensiveDebugFunction()
//@endexclude

anotherFunction();
```

Built with a NODE_ENV of production :

```js
normalFunction();

anotherFunction();
```



## Configuration and Usage

Install via npm

```bash
$ npm install --save preprocess
```

Use the exposed `preprocess` method or the convenience file functions. The context, by default, is the
current ENV config the process (`process.env`)

```js

var pp = require('preprocess');

var text = 'Hi, I am <!-- @echo USERNAME -->';

pp.preprocess(text);
// -> Hi, I am jsoverson

pp.preprocess(text, {USERNAME : "Bob"});
// -> Hi, I am Bob
```

## Contributing
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [grunt][grunt].

## Release History

- 1.0.0 Pulled from grunt-preprocess to stand alone

## License

Copyright OneHealth Solutions, Inc

Written by Jarrod Overson

Licensed under the Apache 2.0 license.
104 changes: 104 additions & 0 deletions lib/preprocess.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* preprocess
* https://github.com/onehealth/preprocess
*
* Copyright (c) 2012 OneHealth Solutions, Inc.
* Written by Jarrod Overson - http://jarrodoverson.com/
* Licensed under the Apache 2.0 license.
*/

/*jshint node:true*/

'use strict';

exports.preprocess = preprocess;
exports.preprocessFile = preprocessFile;
exports.preprocessFileSync = preprocessFileSync;

var path = require('path'),
fs = require('fs'),
_ = require('lodash'),
delim = require('./regexrules');

function preprocessFile(src, dest, context, callback) {
context.src = src;
context.srcDir = path.dirname(src);

fs.readFile(src,function(err,data){
if (err) return callback(err,data);
var parsed = preprocess(data, context, getExtension(src));
fs.writeFile(dest,parsed,callback);
});
}

function preprocessFileSync(src, dest, context) {
context.src = src;
context.srcDir = path.dirname(src);

var data = fs.readFileSync(src);
var parsed = preprocess(data, context, getExtension(src));
return fs.writeFileSync(dest,parsed);
}


function getExtension(filename) {
var ext = path.extname(filename||'').split('.');
return ext[ext.length - 1];
}

function preprocess(src,context,type) {
src = src.toString();
context = context || process.env;

type = type || 'html';

var rv = src;

rv = rv.replace(getRegex(type,'include'),function(match,file,include){
file = (file || '').trim();
var includedSource = fs.readFileSync(path.join(context.srcDir,file));
return includedSource || match + ' not found';
})

rv = rv.replace(getRegex(type,'exclude'),function(match,test,include){
return testPasses(test,context) ? '' : include;
})

rv = rv.replace(getRegex(type,'ifdef'),function(match,test,include){
test = (test || '').trim();
return typeof context[test] !== 'undefined' ? include : '';
})

rv = rv.replace(getRegex(type,'ifndef'),function(match,test,include){
test = (test || '').trim();
return typeof context[test] === 'undefined' ? include : '';
})

rv = rv.replace(getRegex(type,'if'),function(match,test,include){
return testPasses(test,context) ? include : '';
})

rv = rv.replace(getRegex(type,'insert'),function(match,variable) {
return context[(variable || '').trim()];
});

return rv;
}

function getRegex(type, def) {

var isRegex = typeof delim[type][def] === 'string' || delim[type][def] instanceof RegExp;
return isRegex ?
new RegExp(delim[type][def],'gi') :
new RegExp(delim[type][def].start + '((?:.|\n|\r)*?)' + delim[type][def].end,'gi');
}

function getTestTemplate(test) {
test = test || 'true';
test = test.replace(/([^=])=([^=])/g, '$1==$2');
return '<% if ('+test+') { %>true<% }else{ %>false<% } %>'
}

function testPasses(test,context) {
return _.template(getTestTemplate(test),context) === 'true';
}
Loading

0 comments on commit 1e3a576

Please sign in to comment.