Initial check-in.

This commit is contained in:
Ken Elf Mathieu Sternberg 2013-02-06 10:08:33 -08:00
commit a332ceeb73
14 changed files with 398 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/node_modules/
tmp
#*
*~

64
Gruntfile.coffee Normal file
View File

@ -0,0 +1,64 @@
module.exports = (grunt) ->
grunt.initConfig
pkg: grunt.file.readJSON('package.json')
jshint:
files: [ "src/**/*.js", "test/**/*.js" ]
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: {}
clean:
files: ["tmp/"]
coffee:
rubyHaml:
files:
"tasks/ruby-haml.js": "src/ruby-haml.coffee"
options:
bare: false
rubyHaml:
test_html:
files: [
{"tmp/01_straight.html": "test/fixtures/01_straight.haml"}
{"tmp/02_scored.html": "test/fixtures/02_scored.haml"}
]
test_js:
files: [
{"tmp/01_straight.js": "test/fixtures/01_straight.haml"}
{"tmp/02_scored.js": "test/fixtures/02_scored.haml"}
]
options:
templatize: true
nodeunit:
files: [ "test/*.js" ]
watch:
files: "<config:jshint.files>"
tasks: "default"
grunt.loadTasks "tasks"
grunt.loadNpmTasks('grunt-coffee')
grunt.loadNpmTasks('grunt-contrib-watch')
grunt.loadNpmTasks('grunt-contrib-jshint')
grunt.loadNpmTasks('grunt-contrib-nodeunit')
grunt.loadNpmTasks('grunt-contrib-clean')
grunt.registerTask "default", ["coffee:rubyHaml", "jshint", "rubyHaml:test_html", "rubyHaml:test_js", "nodeunit", "clean"]

22
LICENSE-MIT Normal file
View File

@ -0,0 +1,22 @@
Copyright (c) 2012 Elf M. Sternberg
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

73
README.md Normal file
View File

@ -0,0 +1,73 @@
# grunt-ruby-haml
Compile your HTML templates using Ruby
## WHAT!? WHY!?!?!?
Because I like underscore, and underscore templates. They come free
with Backbone. And Ruby's HAML treats them without abusing them.
It's not a great solution, but it's better than trying to write yet
another HAML parser.
And before you get me started on Jade, or Mustache, or whatever:
forget it. Jade is a big learning curve for little reward, and the
rest are templating languages in their own right.
## Getting Started
Make sure you have Ruby and Haml available in you $PATH.
Install this grunt plugin next to your project's [grunt.js
gruntfile][getting_started] with: `npm install grunt-ruby-haml`
Then add this line to your project's `grunt.js` gruntfile:
```javascript
grunt.loadNpmTasks('grunt-ruby-haml');
```
## Documentation
You'll need to install `grunt-ruby-haml`:
npm install grunt-ruby-haml
Then modify your `Gruntfile.js` file by adding the following line:
grunt.loadNpmTasks('grunt-ruby-haml');
Then add some configuration for the plugin like so:
grunt.initConfig({
...
ruby-haml: {
app: {
files: {
"public/index.html": "src/index.haml"
}
options: {
templatize: False
}
}
},
...
});
Then just run `grunt ruby-haml` and enjoy!
Ruby-HAML will, by default, generate HTML. With the 'templatize'
option set to True, it will instead spit out an underscore template
ready to be rendered, wrapped in an AMD-compliant define() call. This
may be useful to some of you who want to use the output of the HAML
engine as a pre-parsed underscore template.
## 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
0.0.1 - Just what I've always run. Don't expect miracles
## License
Copyright (c) 2013 Elf M. Sternberg
Licensed under the MIT license.

54
package.json Normal file
View File

@ -0,0 +1,54 @@
{
"name": "grunt-ruby-haml",
"description": "HAML via the Ruby compiler for Grunt",
"version": "0.0.3",
"homepage": "https://github.com/elfsternberg/grunt-ruby-haml",
"author": {
"name": "Elf M. Sternberg",
"email": "elf.sternberg@gmail.com"
},
"contributors": [
{
"name": "Elf M. Sternberg",
"url": "https://github.com/elfsternberg"
}
],
"repository": {
"type": "git",
"url": "git://github.com/elfsternberg/grunt-ruby-haml.git"
},
"bugs": {
"url": "https://github.com/elfsternberg/grunt-ruby-haml/issues"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/elfsternberg/grunt-ruby-haml/blob/master/LICENSE-MIT"
}
],
"main": "grunt.js",
"engines": {
"node": "*"
},
"scripts": {
"test": "grunt test"
},
"dependencies": {
"grunt": "=0.4.0a",
"coffee-script": "~1.3.1"
},
"devDependencies": {
"grunt": "~0.4.x",
"coffee-script": "~1.3.1",
"grunt-contrib-watch": "~0.1.4",
"grunt-contrib-nodeunit": "~0.1.1",
"grunt-contrib-jshint": "~0.1.0",
"grunt-contrib-clean": ">=0.4.0rc6",
"async": "~0.2.2",
"underscore": "~1.4.4",
"grunt-coffee": "git://github.com/elfsternberg/grunt-coffee.git"
},
"keywords": [
"gruntplugin"
]
}

40
src/ruby-haml.coffee Normal file
View File

@ -0,0 +1,40 @@
#
# grunt-ruby-haml
#
# Copyright (c) 2013 Elf M. Sternberg
# Licensed under the MIT license.
#
_ = require 'underscore'
module.exports = (grunt) ->
hamlize = (src, destPath, options, done) ->
args =
cmd: "haml"
args: [ "--unix-newlines", "--no-escape-attrs", "--double-quote-attributes", src ]
grunt.util.spawn args, (err, result) ->
[ext, result] = if options.templatize
[".js", "define(function() { return " + _.template(result.stdout).source + "});"]
else
["html", result.stdout]
dest = destPath
destPath = (if dest then dest else path.dirname(src))
if destPath.indexOf(ext, destPath.length - ext.length) == -1
dest = path.join(destPath, path.basename(src, ".haml") + ext)
grunt.file.write dest, result
done(null)
grunt.registerMultiTask "rubyHaml", "Compile HAML with Ruby", ->
options = @options({templatize: false})
done = @async()
sources = _.flatten(([i, file.dest] for i in file.src for file in @files when file.src.length > 0), true)
return done() if sources.length is 0
grunt.util.async.forEachSeries sources, ((path, cb) ->
hamlize path[0], path[1], options, cb
), done

62
tasks/ruby-haml.js Normal file
View File

@ -0,0 +1,62 @@
(function() {
var _;
_ = require('underscore');
module.exports = function(grunt) {
var hamlize;
hamlize = function(src, destPath, options, done) {
var args;
args = {
cmd: "haml",
args: ["--unix-newlines", "--no-escape-attrs", "--double-quote-attributes", src]
};
return grunt.util.spawn(args, function(err, result) {
var dest, ext, _ref;
_ref = options.templatize ? [".js", "define(function() { return " + _.template(result.stdout).source + "});"] : ["html", result.stdout], ext = _ref[0], result = _ref[1];
dest = destPath;
destPath = (dest ? dest : path.dirname(src));
if (destPath.indexOf(ext, destPath.length - ext.length) === -1) {
dest = path.join(destPath, path.basename(src, ".haml") + ext);
}
grunt.file.write(dest, result);
return done(null);
});
};
return grunt.registerMultiTask("rubyHaml", "Compile HAML with Ruby", function() {
var done, file, i, options, sources;
options = this.options({
templatize: false
});
done = this.async();
sources = _.flatten((function() {
var _i, _len, _ref, _results;
_ref = this.files;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
file = _ref[_i];
if (file.src.length > 0) {
_results.push((function() {
var _j, _len1, _ref1, _results1;
_ref1 = file.src;
_results1 = [];
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
i = _ref1[_j];
_results1.push([i, file.dest]);
}
return _results1;
})());
}
}
return _results;
}).call(this), true);
if (sources.length === 0) {
return done();
}
return grunt.util.async.forEachSeries(sources, (function(path, cb) {
return hamlize(path[0], path[1], options, cb);
}), done);
});
};
}).call(this);

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>TEST</title>
</head>
<body>
<h1>Just testing</h1>
</body>
</html>

View File

@ -0,0 +1,7 @@
define(function() { return function(obj){
var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};
with(obj||{}){
__p+='<!DOCTYPE html>\n<html xmlns="http://www.w3.org/1999/xhtml">\n <head>\n <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />\n <title>TEST</title>\n </head>\n <body>\n <h1>Just testing</h1>\n </body>\n</html>';
}
return __p;
}});

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>TEST</title>
</head>
<body>
<h1><%= (2 + 2) %></h1>
</body>
</html>

View File

@ -0,0 +1,9 @@
define(function() { return function(obj){
var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};
with(obj||{}){
__p+='<!DOCTYPE html>\n<html xmlns="http://www.w3.org/1999/xhtml">\n <head>\n <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />\n <title>TEST</title>\n </head>\n <body>\n <h1>'+
((__t=( (2 + 2) ))==null?'':__t)+
'</h1>\n </body>\n</html>';
}
return __p;
}});

7
test/fixtures/01_straight.haml vendored Normal file
View File

@ -0,0 +1,7 @@
!!! 5
%html{:xmlns => "http://www.w3.org/1999/xhtml"}
%head
%meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"}/
%title TEST
%body
%h1 Just testing

7
test/fixtures/02_scored.haml vendored Normal file
View File

@ -0,0 +1,7 @@
!!! 5
%html{:xmlns => "http://www.w3.org/1999/xhtml"}
%head
%meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"}/
%title TEST
%body
%h1 <%= (2 + 2) %>

29
test/ruby-haml_test.js Normal file
View File

@ -0,0 +1,29 @@
"use strict";
var grunt = require('grunt'),
fs = require('fs'),
path = require('path'),
files = [
["tmp/01_straight.html", "test/expected/01_straight.html"],
["tmp/02_scored.html", "test/expected/02_scored.html"],
["tmp/01_straight.js", "test/expected/01_straight.js"],
["tmp/02_scored.js", "test/expected/02_scored.js"]
]
fs.existsSync = fs.existsSync ? fs.existsSync : path.existsSync;
exports.coffee = {
setUp: function(done) {
done();
},
'task': function(test) {
test.expect(files.length);
files.forEach(function(file) {
test.equal(grunt.file.read(file[0]), grunt.file.read(file[1]));
});
test.done();
}
};