diff --git a/Cakefile b/Cakefile index 89b1af6..5b25ad4 100644 --- a/Cakefile +++ b/Cakefile @@ -60,7 +60,7 @@ task "dist", "Generate dist/eco.js", -> "strscan": read "node_modules/strscan/lib/strscan.js" "coffee-script": stub "CoffeeScript" - package = for name, source of modules + pkg = for name, source of modules """ '#{name}': function(module, require, exports) { #{source} @@ -89,12 +89,12 @@ task "dist", "Generate dist/eco.js", -> } }; })({ - #{package.join ',\n'} + #{pkg.join ',\n'} })('eco'); """ try - fs.mkdirSync "#{__dirname}/dist", 0755 + fs.mkdirSync "#{__dirname}/dist", 0o755 catch err fs.writeFileSync "#{__dirname}/dist/eco.js", "#{header}\n#{source}" diff --git a/lib/command.js b/lib/command.js index 6fa10e8..2f29916 100644 --- a/lib/command.js +++ b/lib/command.js @@ -1,6 +1,7 @@ +// Generated by CoffeeScript 1.4.0 (function() { - var compile, compileToFile, each, eachFile, eco, exec, fs, indent, mkdir, parseOptions, path, preprocessArgs, printUsage, printVersion, read, stripExtension, sys; - var __slice = Array.prototype.slice; + var compile, compileToFile, each, eachFile, eco, exec, fs, indent, mkdir, parseOptions, path, preprocessArgs, printUsage, printVersion, read, stripExtension, sys, + __slice = [].slice; fs = require("fs"); @@ -20,20 +21,20 @@ }; printVersion = function() { - var package; - package = JSON.parse(fs.readFileSync(__dirname + "/../package.json", "utf8")); - console.error("Eco version " + package.version); + var pkg; + pkg = JSON.parse(fs.readFileSync(__dirname + "/../package.json", "utf8")); + console.error("Eco version " + pkg.version); return process.exit(0); }; preprocessArgs = function(args) { - var arg, char, match, result, _i, _j, _len, _len2, _ref; + var arg, char, match, result, _i, _j, _len, _len1, _ref; result = []; for (_i = 0, _len = args.length; _i < _len; _i++) { arg = args[_i]; if (match = /^-([a-z]{2,})/.exec(arg)) { _ref = match[1].split(''); - for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) { + for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { char = _ref[_j]; result.push("-" + char); } @@ -88,7 +89,9 @@ } } } - if (option) printUsage(); + if (option) { + printUsage(); + } return options; }; @@ -116,13 +119,19 @@ var traverse; traverse = function(root, dir, done) { return fs.readdir(dir, function(err, entries) { - if (err) return callback(err); + if (err) { + return callback(err); + } return each(entries, function(entry, proceed) { var file; - if (entry == null) return done(); + if (entry == null) { + return done(); + } file = path.join(dir, entry); return fs.stat(file, function(err, stat) { - if (err) return callback(err); + if (err) { + return callback(err); + } if (stat.isFile() && /\.eco$/.test(file)) { return callback(null, file, root, proceed); } else if (stat.isDirectory()) { @@ -135,10 +144,14 @@ }); }; return each(files, function(file, proceed) { - if (file == null) return; + if (file == null) { + return; + } return fs.stat(file, function(err, stat) { var root; - if (err) return callback(err); + if (err) { + return callback(err); + } if (stat.isDirectory()) { return traverse(file, file, proceed); } else { @@ -156,7 +169,9 @@ compile = function(infile, identifier, name, callback) { return fs.readFile(infile, "utf8", function(err, source) { var template; - if (err) return callback(err); + if (err) { + return callback(err); + } template = indent(eco.precompile(source), 2); return callback(null, "(function() {\n this." + identifier + " || (this." + identifier + " = {});\n this." + identifier + "[" + (JSON.stringify(name)) + "] = " + (template.slice(2)) + ";\n}).call(this);"); }); @@ -178,10 +193,14 @@ } outfile = path.join(outdir != null ? outdir : root, name + ".js"); return mkdir(path.dirname(outfile), function(err) { - if (err) return callback(err); + if (err) { + return callback(err); + } return compile(infile, identifier, name, function(err, result) { return fs.writeFile(outfile, result + "\n", "utf8", function(err) { - if (err) return callback(err); + if (err) { + return callback(err); + } return callback(null, outfile, name); }); }); @@ -190,29 +209,45 @@ exports.run = function(args) { var infile, name, options; - if (args == null) args = process.argv.slice(2); + if (args == null) { + args = process.argv.slice(2); + } options = parseOptions(args); if (options.stdio) { - if (options.files.length || options.output) printUsage(); + if (options.files.length || options.output) { + printUsage(); + } process.openStdin(); return read(process.stdin, function(source) { return sys.puts(eco.precompile(source)); }); } else if (options.print) { - if (options.files.length !== 1 || options.output) printUsage(); + if (options.files.length !== 1 || options.output) { + printUsage(); + } infile = options.files[0]; name = stripExtension(path.basename(infile)); return compile(infile, options.identifier, name, function(err, result) { - if (err) throw err; + if (err) { + throw err; + } return sys.puts(result); }); } else { - if (!options.files.length) printUsage(); + if (!options.files.length) { + printUsage(); + } return eachFile(options.files, function(err, infile, root, proceed) { - if (err) throw err; - if (infile == null) return; + if (err) { + throw err; + } + if (infile == null) { + return; + } return compileToFile(infile, options.identifier, root, options.output, function(err, outfile, name) { - if (err) throw err; + if (err) { + throw err; + } console.error("" + (JSON.stringify(name)) + ": " + infile + " -> " + outfile); return proceed(); }); diff --git a/lib/compiler.js b/lib/compiler.js index 0eff0e5..75eabbb 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -1,3 +1,4 @@ +// Generated by CoffeeScript 1.4.0 (function() { var CoffeeScript, indent, precompile, preprocess; diff --git a/lib/index.js b/lib/index.js index bca5ac8..7c6b9c4 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,3 +1,4 @@ +// Generated by CoffeeScript 1.4.0 (function() { var compile, eco, precompile, preprocess, _ref; @@ -6,9 +7,9 @@ preprocess = require("./preprocessor").preprocess; module.exports = eco = function(source) { - var _base, _ref2; + var _base, _ref1; if (eco.cache) { - return (_ref2 = (_base = eco.cache)[source]) != null ? _ref2 : _base[source] = compile(source); + return (_ref1 = (_base = eco.cache)[source]) != null ? _ref1 : _base[source] = compile(source); } else { return compile(source); } diff --git a/lib/preprocessor.js b/lib/preprocessor.js index 5a33c64..dba8303 100644 --- a/lib/preprocessor.js +++ b/lib/preprocessor.js @@ -1,3 +1,4 @@ +// Generated by CoffeeScript 1.4.0 (function() { var Preprocessor, Scanner, util; @@ -38,6 +39,7 @@ Preprocessor.prototype.printString = function(string) { if (string.length) { + string = string.replace(/\s+\s+/g, '>'); return this.record("__out.push " + (util.inspectString(string))); } }; @@ -47,6 +49,7 @@ }; Preprocessor.prototype.recordCode = function(code) { + code = code.replace(/\s+/g, ' '); if (code !== "end") { if (this.options.print) { if (this.options.safe) { @@ -71,7 +74,9 @@ Preprocessor.prototype.dedent = function() { this.level--; - if (this.level < 0) this.fail("unexpected dedent"); + if (this.level < 0) { + this.fail("unexpected dedent"); + } if (this.captures[0] === this.level) { this.captures.shift(); return this.dedent(); diff --git a/lib/scanner.js b/lib/scanner.js index cd7258d..ebac68c 100644 --- a/lib/scanner.js +++ b/lib/scanner.js @@ -1,3 +1,4 @@ +// Generated by CoffeeScript 1.4.0 (function() { var Scanner, StringScanner, trim; @@ -9,8 +10,8 @@ Scanner.modePatterns = { data: /(.*?)(<%%|<%\s*(\#)|<%(([=-])?)|\n|$)/, - code: /(.*?)((((:|(->|=>))\s*))?%>|\n|$)/, - comment: /(.*?)(%>|\n|$)/ + code: /([\s\S]*?)((((:|(->|=>))\s*))?%>|$)/, + comment: /([\s\S]*?)(%>|$)/ }; Scanner.dedentablePattern = /^(end|when|else|catch|finally)(?:\W|$)/; @@ -95,22 +96,24 @@ Scanner.prototype.scanCode = function(callback) { var code; - if (this.tail === "\n") { - return callback(["fail", "unexpected newline in code block"]); - } else if (this.tail) { + if (this.tail) { this.mode = "data"; code = trim(this.flush()); - if (this.arrow) code += " " + this.arrow; - if (this.isDedentable(code)) callback(["dedent"]); + if (this.arrow) { + code += " " + this.arrow; + } + if (this.isDedentable(code)) { + callback(["dedent"]); + } callback(["recordCode", code]); - if (this.directive) return callback(["indent", this.arrow]); + if (this.directive) { + return callback(["indent", this.arrow]); + } } }; Scanner.prototype.scanComment = function(callback) { - if (this.tail === "\n") { - return callback(["fail", "unexpected newline in code block"]); - } else if (this.tail) { + if (this.tail) { this.mode = "data"; return this.buffer = ""; } diff --git a/lib/util.js b/lib/util.js index 80fed3e..a895a63 100644 --- a/lib/util.js +++ b/lib/util.js @@ -1,3 +1,4 @@ +// Generated by CoffeeScript 1.4.0 (function() { var repeat, specialCharacters; @@ -42,7 +43,9 @@ return specialCharacters[character]; } else { code = character.charCodeAt(0).toString(16); - if (code.length === 1) code = "0" + code; + if (code.length === 1) { + code = "0" + code; + } return "\\u00" + code; } }); diff --git a/src/command.coffee b/src/command.coffee index 7c44283..e9e9ed4 100644 --- a/src/command.coffee +++ b/src/command.coffee @@ -22,8 +22,8 @@ printUsage = -> process.exit 1 printVersion = -> - package = JSON.parse fs.readFileSync __dirname + "/../package.json", "utf8" - console.error "Eco version #{package.version}" + pkg = JSON.parse fs.readFileSync __dirname + "/../package.json", "utf8" + console.error "Eco version #{pkg.version}" process.exit 0 preprocessArgs = (args) -> diff --git a/src/preprocessor.coffee b/src/preprocessor.coffee index f698dd1..f2b376b 100644 --- a/src/preprocessor.coffee +++ b/src/preprocessor.coffee @@ -25,12 +25,16 @@ module.exports = class Preprocessor printString: (string) -> if string.length + string = string + .replace(/\s+\s+/g, '>') @record "__out.push #{util.inspectString string}" beginCode: (options) -> @options = options recordCode: (code) -> + code = code.replace /\s+/g, ' ' if code isnt "end" if @options.print if @options.safe diff --git a/src/scanner.coffee b/src/scanner.coffee index 2b6e94a..4c14eb7 100644 --- a/src/scanner.coffee +++ b/src/scanner.coffee @@ -4,8 +4,8 @@ module.exports = class Scanner @modePatterns: data: /(.*?)(<%%|<%\s*(\#)|<%(([=-])?)|\n|$)/ - code: /(.*?)((((:|(->|=>))\s*))?%>|\n|$)/ - comment: /(.*?)(%>|\n|$)/ + code: /([\s\S]*?)((((:|(->|=>))\s*))?%>|$)/ + comment: /([\s\S]*?)(%>|$)/ @dedentablePattern: /^(end|when|else|catch|finally)(?:\W|$)/ @@ -73,10 +73,7 @@ module.exports = class Scanner callback ["beginCode", print: @directive?, safe: @directive is "-"] scanCode: (callback) -> - if @tail is "\n" - callback ["fail", "unexpected newline in code block"] - - else if @tail + if @tail @mode = "data" code = trim @flush() code += " #{@arrow}" if @arrow @@ -86,10 +83,7 @@ module.exports = class Scanner callback ["indent", @arrow] if @directive scanComment: (callback) -> - if @tail is "\n" - callback ["fail", "unexpected newline in code block"] - - else if @tail + if @tail @mode = "data" @buffer = "" diff --git a/test/fixtures/newlines.coffee b/test/fixtures/newlines.coffee new file mode 100644 index 0000000..7bdebb5 --- /dev/null +++ b/test/fixtures/newlines.coffee @@ -0,0 +1,2 @@ +func { foo: bar } +__out.push '\n' diff --git a/test/fixtures/newlines.eco b/test/fixtures/newlines.eco new file mode 100644 index 0000000..e179a89 --- /dev/null +++ b/test/fixtures/newlines.eco @@ -0,0 +1,3 @@ +<% func { + foo: bar +} %> diff --git a/test/test_express.coffee b/test/test_express.coffee deleted file mode 100644 index 7dda9d1..0000000 --- a/test/test_express.coffee +++ /dev/null @@ -1,30 +0,0 @@ -eco = require ".." -express = require "express" -http = require "http" - -module.exports = - "registering eco in an express application": (test) -> - test.expect 2 - - app = express.createServer() - app.register ".eco", eco - app.set "views", __dirname + "/fixtures" - app.get "/hello/:name", (req, res) -> - res.render "hello.eco", name: req.params.name, layout: false - - app.listen -> - host = "localhost" - {port} = app.address() - path = "/hello/Sam" - - http.get {host, port, path}, (res) -> - test.same 200, res.statusCode - - body = "" - res.setEncoding "utf8" - res.on "data", (data) -> body += data - res.on "end", -> - test.same "Hello, Sam.\nI\'M SHOUTING AT YOU, SAM!\n", body - - app.close() - test.done() diff --git a/test/test_preprocessor.coffee b/test/test_preprocessor.coffee index 58b79c0..31d9df2 100644 --- a/test/test_preprocessor.coffee +++ b/test/test_preprocessor.coffee @@ -14,6 +14,10 @@ module.exports = test.same fixture("helpers.coffee"), preprocess fixture("helpers.eco") test.done() + "preprocessing fixtures/newlines.eco": (test) -> + test.same fixture("newlines.coffee"), preprocess fixture("newlines.eco") + test.done() + "unexpected dedent": (test) -> test.expect 1 try @@ -27,17 +31,6 @@ module.exports = test.same "Parse error on line 4: unexpected dedent", err.toString() test.done() - "unexpected newline in code block": (test) -> - test.expect 1 - try - preprocess """ - <%= item.price if - item = @items?[0] %> - """ - catch err - test.same "Parse error on line 1: unexpected newline in code block", err.toString() - test.done() - "unexpected end of template": (test) -> test.expect 1 try diff --git a/test/test_scanner.coffee b/test/test_scanner.coffee index cfde7a8..cd3942d 100644 --- a/test/test_scanner.coffee +++ b/test/test_scanner.coffee @@ -76,11 +76,11 @@ module.exports = test.same ["recordCode", "'<%%'"], tokens.shift() test.done() - "unexpected newline in code block": (test) -> - tokens = scan "foo\nhello <% do 'thing'\n %>" + "newlines in code blocks": (test) -> + tokens = scan "foo\nhello <% func {\nfoo: bar\n} %>" test.same ["printString", "foo\nhello "], tokens.shift() test.same ["beginCode", print: false, safe: false], tokens.shift() - test.same ["fail", "unexpected newline in code block"], tokens.shift() + test.same ["recordCode", "func {\nfoo: bar\n}"], tokens.shift() test.done() "unexpected end of template": (test) ->