Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes and improvements #36

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
41 changes: 41 additions & 0 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion src/environment.co
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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}
Expand Down
3 changes: 1 addition & 2 deletions src/expression.pegco
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

->
compilation_ctx = arguments[2] ? {}
compilation_ctx.filters ?= {}
Expand Down Expand Up @@ -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

Expand Down
25 changes: 18 additions & 7 deletions src/filters.co
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down
30 changes: 29 additions & 1 deletion src/helpers.co
Original file line number Diff line number Diff line change
Expand Up @@ -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 }

4 changes: 2 additions & 2 deletions src/main.co
Original file line number Diff line number Diff line change
@@ -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 }

37 changes: 28 additions & 9 deletions src/nodes.co
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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__
Expand Down Expand Up @@ -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});"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -560,5 +578,6 @@ exports <<< {
\continue : NodeContinue
\break : NodeBreak
\call : NodeCall
\raw : NodeRaw
}

18 changes: 9 additions & 9 deletions test/parser.co
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"

##
Expand Down Expand Up @@ -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'

Expand Down Expand Up @@ -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'

Expand Down
2 changes: 1 addition & 1 deletion test/templates/test-include.tpl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% let variable = "bloup" %}
{% set variable = "bloup" %}
{% macro test () %}
Yoyo {{ variable }}
{% endmacro %}
Expand Down