diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json new file mode 100644 index 0000000..d14e80a --- /dev/null +++ b/npm-shrinkwrap.json @@ -0,0 +1,41 @@ +{ + "name" : "jinjs", + "version" : "0.3.6", + "dependencies" : { + "optimist" : { + "version" : "0.2.3", + "dependencies" : { + "wordwrap" : { + "version" : "0.0.2" + } + } + }, + "pegco" : { + "version" : "0.0.1", + "dependencies" : { + "pegjs" : { + "version" : "0.6.2" + } + } + }, + "coco" : { + "version" : "0.6.7" + }, + "rbuild" : { + "version" : "0.0.5", + "dependencies" : { + "async" : { + "version" : "0.1.22" + } + } + }, + "vows" : { + "version" : "0.6.3", + "dependencies" : { + "eyes" : { + "version" : "0.1.7" + } + } + } + } +} \ No newline at end of file diff --git a/src/environment.co b/src/environment.co index 50fdebe..9903240 100644 --- a/src/environment.co +++ b/src/environment.co @@ -12,6 +12,8 @@ class Environment return eval t ({@utils ? require("./utils"), @filters ? require("./filters"), @parser ? new Parser!, @pre_compile_func ? "", @require_exp ? 'require'} ? {}) -> + @outputUndefinedVariable = false + @outputUndefinedVariableWithBrackets = false getTemplateFromString: function (str) try @@ -28,7 +30,7 @@ class Environment str = @pre_compile_func str if @pre_compile_func ast = @parser.parse str, compilation_ctx - opts = {__indent__: 1, @utils, @filters} + opts = {__indent__: 1, @utils, @filters, @outputUndefinedVariable, @outputUndefinedVariableWithBrackets} compilation_ctx = filters_used: {} compilation_ctx <<< {@filters, @utils} diff --git a/src/expression.pegco b/src/expression.pegco index f36da77..a9fa239 100644 --- a/src/expression.pegco +++ b/src/expression.pegco @@ -1,4 +1,3 @@ - -> compilation_ctx = arguments[2] ? {} compilation_ctx.filters ?= {} @@ -320,7 +319,7 @@ tag_for / key:identifier COMMA value:identifier IN exp:expression -> return key: key, value: value, condition: exp -tag_let +tag_set = variable_name:identifier ASSIGN expression:expression -> return variable_name: variable_name, expression: expression diff --git a/src/filters.co b/src/filters.co index 56ecc83..674aefb 100644 --- a/src/filters.co +++ b/src/filters.co @@ -186,13 +186,13 @@ exports import do if value < 1024 return "#{value}" if value < 1024 * 1024 - val = val / 1024 + val = value / 1024 unit = "Kb" else if value < 1024 * 1024 * 1024 - val = val / (1024 * 1024) + val = value / (1024 * 1024) unit = "Mb" else - val = val / (1024 * 1024 * 1024) + val = value / (1024 * 1024 * 1024) unit = "Gb" strval = "#{Math.round val}" @@ -203,7 +203,7 @@ exports import do $float: function (value) res = parseFloat value - return 0.0 if res is NaN + return 0.0 if isNaN res return res $forceescape: function (value) @@ -441,10 +441,21 @@ exports import do obj = obj[a] return obj - $reverse: function (arr) - new_arr = arr.splice 0 + $reverse: function (arr, keep_array) + keep_array = keep_array or false + new_arr = arr + if \number is typeof arr + new_arr = new_arr.toString() + new_arr = new_arr.split("") + new_arr = new_arr.splice(0) + else if \string is typeof arr + new_arr = new_arr.split("") + new_arr = new_arr.splice(0) + else if arr instanceof Array + new_arr = new_arr.splice(0) + else throw new Error("Unsupported type \"" + typeof arr + "\" for reverse") new_arr.reverse() - return new_arr + return (if (keep_array) then new_arr else new_arr.join("")) $round: function (value, precision ? 0, method ? 'common') if method is \common diff --git a/src/helpers.co b/src/helpers.co index c2f66ec..3bc1271 100644 --- a/src/helpers.co +++ b/src/helpers.co @@ -20,5 +20,33 @@ function registerExtension (ext, filter) # registerExtension \.pwi, (str) -> pwilang.parse str # registerExtension \.pwx, (str) -> pwilang.parse str -exports import { registerExtension } +/** + * Register flag to output undefined variables + * @param output: flag to output undefined variable name + * @param withBrackets: flag to output undefined variable name with brackets + */ +function outputUndefinedVariable (output, withBrackets) + output ?= true + withBrackets ?= false + + defaultEnvironment.outputUndefinedVariable = output + defaultEnvironment.outputUndefinedVariableWithBrackets = withBrackets + +/** + * Options for JinJS + * @param opts: object where the properties are set + */ +function options (opts) + opts ?= {} + + # Check if extensions passed + if opts.extensions + for index, extension in opts.extensions + registerExtension extension.ext, extension.filter + + # Check if outputUndefinedVariable is defined + if opts.outputUndefinedVariable + outputUndefinedVariable opts.outputUndefinedVariable, opts.outputUndefinedVariableWithBrackets + +exports import { registerExtension, outputUndefinedVariable, options } diff --git a/src/main.co b/src/main.co index 232a975..e2dbdfc 100644 --- a/src/main.co +++ b/src/main.co @@ -1,6 +1,6 @@ { defaultEnvironment, Environment } = require \./environment -{ registerExtension } = require \./helpers +{ registerExtension, outputUndefinedVariable, options } = require \./helpers { compile } = require \./express -exports <<< { defaultEnvironment, registerExtension, Environment, compile } +exports <<< { defaultEnvironment, registerExtension, outputUndefinedVariable, options, Environment, compile } diff --git a/src/nodes.co b/src/nodes.co index 59c6f29..6b9ae1f 100644 --- a/src/nodes.co +++ b/src/nodes.co @@ -1,11 +1,10 @@ - { parse:make_expression } = require \./expression make_parse_rule = (rule_name) -> return (contents, ctx) -> make_expression contents, rule_name, ctx parse_for = make_parse_rule \tag_for -parse_let = make_parse_rule \tag_let +parse_set = make_parse_rule \tag_set parse_macro = make_parse_rule \tag_macro parse_extends = make_expression parse_block = make_parse_rule \tag_block @@ -108,7 +107,12 @@ class NodePrint extends Node (specs) -> super ... compile: function (opts, ctx) - return "_res += ((_ref = #{make_expression @contents, ctx}) !== undefined && _ref !== null ? _ref : '').toString();" + output = '' + if (opts.outputUndefinedVariableWithBrackets) + output = "{{#{@contents}}}" + else if (opts.outputUndefinedVariable) + output = @contents + return "_res += ((_ref = #{make_expression @contents, ctx}) !== undefined && _ref !== null ? _ref : '#{output}').toString();" class NodeTag extends Node @tag = \__tag__ @@ -242,13 +246,13 @@ class NodeAbspath extends NodeTag /** * */ -class NodeLet extends NodeTag - @tag = \let +class NodeSet extends NodeTag + @tag = \set (specs) -> super ... compile: function (opts, ctx) - { variable_name, expression } = parse_let @contents, ctx + { variable_name, expression } = parse_set @contents, ctx ctx[variable_name] = true # The variable name is now accessible to the rest of the template. return res = "var #{variable_name} = ($$.#{variable_name} = #{expression});" @@ -452,6 +456,19 @@ class NodeIf extends NodeTagContainer }""" return res +/** + * Raw Node + */ +class NodeRaw extends NodeTagContainer + @tag = \raw + @until = \endraw + + (specs) -> + super ... + + compile : function (opts, ctx) + console.dir @ + return "_res += 'ffs';"; class NodeElseFor extends NodeTagContainer @tag = \else @@ -542,13 +559,14 @@ class NodeFor extends NodeTagContainer """ exports <<< { - NodeIf, NodeDo, NodeLet, NodeFor, NodeMacro, NodeList, NodeBasic, + NodeIf, NodeDo, NodeSet, NodeFor, NodeMacro, NodeList, NodeBasic, NodePrint, NodeComment, NodeExtends, NodeInclude, NodeImport, NodeFromImport, - NodeContinue, NodeCall + NodeContinue, NodeCall, NodeRaw default_nodes: do \if : NodeIf \do : NodeDo - \let : NodeLet + \set : NodeSet + \let : NodeSet #Deprecated \for : NodeFor \macro : NodeMacro \extends : NodeExtends @@ -560,5 +578,6 @@ exports <<< { \continue : NodeContinue \break : NodeBreak \call : NodeCall + \raw : NodeRaw } diff --git a/test/parser.co b/test/parser.co index 327a741..f5403cc 100755 --- a/test/parser.co +++ b/test/parser.co @@ -63,8 +63,8 @@ suite = require \vows .describe "Expressions Test Suite" suite.addBatch do - "The {% let %} tag": do - topic: parse "{% let toto = 1 %}TXT" + "The {% set %} tag": do + topic: parse "{% set toto = 1 %}TXT" "Lets us assign to a variable that is later exported": (res) -> equal res.ctx.toto, 1 @@ -73,10 +73,10 @@ suite.addBatch do equal res.txt, 'TXT' "does not let us assign to reserved-words variables": (res) -> - parseError -> _parse "{% let instanceof = 3 %}" + parseError -> _parse "{% set instanceof = 3 %}" "can have their results even across new lines": -> - res = _parse "{% let toto\n=\n 1 %}{{ toto }}" + res = _parse "{% set toto\n=\n 1 %}{{ toto }}" equal res.txt, "1" ## @@ -340,7 +340,7 @@ suite.addBatch do equal res.txt, 'foo' "gets to modify the context": -> - included = compile "{% let foo = 'bar' %}" + included = compile "{% set foo = 'bar' %}" res = _parse "{% include included %}{{ foo }}", foo: "foo", included: included equal res.txt, 'bar' @@ -382,22 +382,22 @@ suite.addBatch do "The {% import %} tag": do "allows us to import variables from another template to another": -> - imported = compile "{% let foo = 'bar' %}" + imported = compile "{% set foo = 'bar' %}" res = _parse "{% from imported import foo %}{{ foo }}", imported: imported equal res.txt, 'bar' "allows us to import a whole template as a module": -> - imported = compile "{% let foo = 'bar' %}" + imported = compile "{% set foo = 'bar' %}" res = _parse "{% import imported as imp %}{{ imp.foo }}", imported: imported equal res.txt, 'bar' "by default does not expose the current context to the imported module": -> - imported = compile "{% let foo = 'bar' %}" + imported = compile "{% set foo = 'bar' %}" res = _parse "{% import imported as toto %}{{ foo }}", imported: imported, foo: 'foo' equal res.txt, 'foo' "can pass the context to the imported template": -> - imported = compile "{% let foo = bar + 'foo' %}" + imported = compile "{% set foo = bar + 'foo' %}" res = _parse "{% import imported as toto with context %}{{ toto.foo }}", imported: imported, bar: 'bar' equal res.txt, 'barfoo' diff --git a/test/templates/test-include.tpl b/test/templates/test-include.tpl index 662887d..e84566f 100644 --- a/test/templates/test-include.tpl +++ b/test/templates/test-include.tpl @@ -1,4 +1,4 @@ -{% let variable = "bloup" %} +{% set variable = "bloup" %} {% macro test () %} Yoyo {{ variable }} {% endmacro %}