olado/doT — pull request #110 by joelpurra (2014-02-12 21:56:17+00:00)
Title: Partials useParams fix to allow square bracket properties

Was trying to use [doT 1.0.0+ partials with parameters](https://github.com/olado/doT#added-parameters-support-in-partials), but ran into problems trying to pass in something like ` myJsonObject["property-with-dashes"]`. The original `useParams` looked weird (and it's undocumented), so rewrote the parameter part, and fixed some related problems at the same time.

- [x] Square bracket object properties, `it['bar']`, `it['bar baz']`
- [x] Arrays with index, `it[1]`
- [x] Square bracket object properties with variables `it[myvar]` (untested)
- [x] Deep object addressing, `it['bar baz'].qux[1]`
- [x] Uppercase or mixed case variable names

Commited new Mocha tests separately.

### Usage example

```
{{##def.tmp:input:

{{!input.foo}}

#}}

{{#def.tmp:myJsonObject["property-with-dashes"]}}
```

If this patch doesn't get accepted, you can still use it by changing the settings:

```javascript
doT.templateSettings.useParams = /(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*((?:[_a-z$][\w$]+)(?:\.[_a-z$][\w$]+|\[(?:(?:[_a-z$][\w$]+)|\d+|(["'])(?![^\\]\4).+\4)\])*)\s*$/i;
```

---

## Appendices

Regexp with test data. Use for example [regexpal.com](http://regexpal.com/) with *Case insensitive (i)* and `^$` *match at line breaks (m)*.

### Original `useParams` regex

```regex
(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})
```

### Naïve fix, matches too many rows

```regex
(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*((?:[\w$\.]+|\[[^\]]+\])+)
```

### Better fix

```regex
(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*((?:[_a-z$][\w$]+)(?:\.[_a-z$][\w$]+|\[(?:(?:[_a-z$][\w$]+)|\d+|(["'])(?![^\\]\4).+\4)\])*)\s*$
```

### Test data

```
// This block should match the entire row for all rows
def.fnname:param
#def.fnname:param
def.fnname:param.foo
def.fnname:param['foo']
def.fnname:param["foo"]
def.fnname:param['foo bar']
def.fnname:param["foo bar"]
def.fnname:param[01234]
def.fnname:param[varname]
def.fnname:param.foo.qux["quux"][43210]
def.fnname:param['foo'].qux["quux"][43210]
def.fnname:param["foo"].qux["quux"][43210]
def.fnname:param['foo bar'].qux["quux"][43210]
def.fnname:param["foo bar"].qux["quux"][43210]
def.fnname:param[01234].qux["quux"][43210]
def.fnname:param[varname].qux["quux"][43210]
def.fnname:param[varname].qux["quåäö+ππππux"][43210]
def.fnname:Param
def.fnname:Param.Foo
def.fnname:Param['Foo Bar']

// This block should not match any part of any rows
def.fnname:param'foo'
def.fnname:param"foo bar"
def.fnname:param.01234
def.fnname:param.foo.qux."quux".43210
def.fnname:param'foo bar'.qux"quux".43210
def.fnname:param.
#def.fnname:param.
def.fnname:param.foo.
def.fnname:param['foo bar'].
```