From a3bd24b43bce33bdfc7ff505588e0ad5ad6e684d Mon Sep 17 00:00:00 2001 From: Seth Kinast Date: Tue, 9 Sep 2014 15:42:48 -0700 Subject: [PATCH] Treat formats and buffers as interchangeable when they are mixed together. During the compiler's optimization pass, "format" globs (basically whitespace) are stripped out. The remaining strings, "buffers", are concatenated into a single entity. If whitespace compression is disabled, formats and buffers are all written, but the two types are not concatenated together. Because most code is broken up by newlines, this results in highly-inefficient chunking of writes that-- in the case of large templates-- causes Dust to exceed the call stack limit. This patch adds dust.config.whitespace (set by default for now to false for backwards compatibility; by default there is zero change with or without the patch) to toggle the whitespace stripping behavior. When the flag is set to true (respect whitespace), the new format/buffer concat logic is invoked. Also adds --whitespace=true|false (default false) flag to dustc. Closes #498 --- .jshintrc | 2 +- bin/dustc | 27 ++++++++++++++++++++------- lib/compiler.js | 34 +++++++++++++++++++--------------- lib/dust.js | 26 ++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 23 deletions(-) diff --git a/.jshintrc b/.jshintrc index cac993b7..3ad6bd6d 100644 --- a/.jshintrc +++ b/.jshintrc @@ -12,7 +12,7 @@ "eqnull": true, "browser": true, "globals": { - "jQuery": true, + "jQuery": true, "require": true, "module": true } diff --git a/bin/dustc b/bin/dustc index b2f52e7b..c66b0840 100755 --- a/bin/dustc +++ b/bin/dustc @@ -3,26 +3,39 @@ var path = require('path'), fs = require('fs'), sys = require('util'), - dust = require('../lib/server'), + dust = require('../lib/server'); + +var ARG_REGEX = /^--?([a-z][0-9a-z-]*)(?:=([^\s]+))?$/i, args = process.argv.slice(1), name = null; -args = args.filter(function (arg) { - var match; +args = args.filter(function(arg) { + var match = arg.match(ARG_REGEX), + val; + + if (!match) { + return true; + } - if (match = arg.match(/^--?([a-z][0-9a-z-]*)(?:=([^\s]+))?$/i)) { arg = match[1] } - else { return arg } + arg = match[1]; + val = match[2]; switch (arg) { case 'h': case 'help': - sys.puts("usage: dustc [{-n|--name}=] {sourcefilename|-} [destination]"); + sys.puts("usage: dustc [{-n|--name}=] [--whitespace=true|false] {source|-} [destination]"); process.exit(0); + break; case 'n': case 'name': - name = match[2]; + name = val; + break; + case 'whitespace': + dust.config.whitespace = (val === 'true'); break; } + + return false; }); var input = args[1]; diff --git a/lib/compiler.js b/lib/compiler.js index 939d7787..1a595ee0 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -11,7 +11,7 @@ var compiler = {}, isArray = dust.isArray; - + compiler.compile = function(source, name) { // the name parameter is optional. // this can happen for templates that are rendered immediately (renderSource which calls compileFn) or @@ -21,7 +21,7 @@ if (!name && name !== null) { throw new Error('Template name parameter cannot be undefined when calling dust.compile'); } - + try { var ast = filterAST(parse(source)); return compile(ast, name); @@ -48,7 +48,7 @@ body: compactBuffers, buffer: noop, special: convertSpecial, - format: nullify, // TODO: convert format + format: format, reference: visit, '#': visit, '?': visit, @@ -105,9 +105,10 @@ for (i=1, len=node.length; i