gettext-handlebars
Advanced tools
Comparing version 0.5.0 to 0.6.0
119
index.js
@@ -11,52 +11,62 @@ 'use strict'; | ||
var gettextSpec = ['msgid']; | ||
var ngettextSpec = ['msgid', 'msgid_plural']; | ||
var pgettextSpec = ['msgctxt', 'msgid']; | ||
var npgettextSpec = ['msgctxt', 'msgid', 'msgid_plural']; | ||
// default JavaScript keywords from | ||
// https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/xgettext-Invocation.html | ||
keywordSpec = keywordSpec || { | ||
gettext: gettextSpec, | ||
_: gettextSpec, | ||
_: { | ||
msgid: 0 | ||
}, | ||
gettext: { | ||
msgid: 0 | ||
}, | ||
dgettext: { | ||
msgid: 1 | ||
}, | ||
dcgettext: { | ||
msgid: 1 | ||
}, | ||
ngettext: { | ||
msgid: 0, | ||
msgid_plural: 1 | ||
}, | ||
dngettext: { | ||
msgid: 1, | ||
msgid_plural: 2 | ||
}, | ||
pgettext: { | ||
msgctxt: 0, | ||
msgid: 1 | ||
}, | ||
dpgettext: { | ||
msgctxt: 1, | ||
msgid: 2 | ||
} | ||
}; | ||
ngettext: ngettextSpec, | ||
n_: ngettextSpec, | ||
Object.keys(keywordSpec).forEach(function (keyword) { | ||
var positions = keywordSpec[keyword]; | ||
pgettext: pgettextSpec, | ||
p_: pgettextSpec, | ||
if ('msgid' in positions) { | ||
return; | ||
} else if (Array.isArray(positions) && positions.indexOf('msgid') >= 0) { | ||
// maintain backwards compatibility with `_: ['msgid']` format | ||
keywordSpec[keyword] = positions.reduce(function (result, key, idx) { | ||
result[key] = idx; | ||
npgettext: npgettextSpec, | ||
np_: npgettextSpec | ||
}; | ||
return result; | ||
}, {}); | ||
} else if (Array.isArray(positions) && positions.length > 0) { | ||
// maintain backwards compatibility with `_: [0]` format | ||
var order = ['msgid', 'msgid_plural']; | ||
// maintain backwards compatibility with `_: [0]` format | ||
keywordSpec = Object.keys(keywordSpec).reduce(function (spec, keyword) { | ||
spec[keyword] = keywordSpec[keyword].reduce(function (a, param, index) { | ||
if (typeof param === 'number') { | ||
if (param > a.length) { | ||
// grow array | ||
for (var i = 0; i < param - a.length; i++) { | ||
a.push('ignored' + i); | ||
} | ||
} | ||
keywordSpec[keyword] = positions.slice(0).reduce(function (result, pos, idx) { | ||
result[order[idx]] = pos; | ||
if (index === 0) { | ||
a[param] = 'msgid'; | ||
} else if (index === 1) { | ||
a[param] = 'msgid_plural'; | ||
} else { | ||
throw new Error('Too many integers passed for keyword ' + keyword); | ||
} | ||
} else { | ||
a.push(param); | ||
} | ||
return result; | ||
}, {}); | ||
} | ||
}); | ||
return a; | ||
}, []); | ||
return spec; | ||
}, {}); | ||
Object.keys(keywordSpec).forEach(function (keyword) { | ||
if (keywordSpec[keyword].indexOf('msgid') === -1) { | ||
throw new Error('Every keyword must have a msgid parameter, but "' + keyword + '" doesn\'t have one'); | ||
if (!('msgid' in keywordSpec[keyword])) { | ||
throw new Error('Every keyword must have a msgid key, but "' + keyword + '" doesn\'t have one'); | ||
} | ||
@@ -91,13 +101,12 @@ }); | ||
if (keywords.indexOf(statement.path.original) !== -1) { | ||
var spec = keywordSpec[statement.path.original], | ||
params = statement.params, | ||
msgidParam = params[spec.indexOf('msgid')]; | ||
var spec = keywordSpec[statement.path.original]; | ||
var params = statement.params; | ||
var msgidParam = params[spec.msgid]; | ||
if (msgidParam) { // don't extract {{gettext}} without param | ||
var msgid = msgidParam.original, | ||
contextIndex = spec.indexOf('msgctxt'); | ||
var msgid = msgidParam.original; | ||
var contextIndex = spec.msgctxt; | ||
var context = null; // null context is *not* the same as empty context | ||
if (contextIndex >= 0) { | ||
if (contextIndex !== undefined) { | ||
var contextParam = params[contextIndex]; | ||
@@ -122,4 +131,4 @@ | ||
// make sure plural forms match | ||
var pluralIndex = spec.indexOf('msgid_plural'); | ||
if (pluralIndex !== -1) { | ||
var pluralIndex = spec.msgid_plural; | ||
if (pluralIndex !== undefined) { | ||
var pluralParam = params[pluralIndex]; | ||
@@ -145,7 +154,7 @@ | ||
spec.forEach(function(prop, i) { | ||
var param = params[i]; | ||
Object.keys(spec).forEach(function(prop) { | ||
var param = params[spec[prop]]; | ||
if (param && param.type === 'StringLiteral') { | ||
msgs[key][prop] = params[i].original; | ||
msgs[key][prop] = params[spec[prop]].original; | ||
} | ||
@@ -173,3 +182,3 @@ }); | ||
// subexpressions as params | ||
if (statement.params ) { | ||
if (statement.params) { | ||
statement.params.reduce(isMsg, msgs); | ||
@@ -176,0 +185,0 @@ } |
{ | ||
"name": "gettext-handlebars", | ||
"version": "0.5.0", | ||
"version": "0.6.0", | ||
"description": "Extract translatable strings from Handlebars templates", | ||
@@ -34,4 +34,4 @@ "main": "index.js", | ||
"devDependencies": { | ||
"eslint": "2.7.0", | ||
"mocha": "2.4.5" | ||
"eslint": "3.7.1", | ||
"mocha": "3.1.0" | ||
}, | ||
@@ -38,0 +38,0 @@ "dependencies": { |
@@ -5,27 +5,43 @@ # gettext-handlebars [![build status](https://secure.travis-ci.org/smhg/gettext-handlebars.png)](http://travis-ci.org/smhg/gettext-handlebars) | ||
It can be used stand-alone or through [gmarty/gettext](https://github.com/gmarty/xgettext). | ||
It can be used stand-alone or through [xgettext-template](https://github.com/gmarty/xgettext). | ||
### API | ||
#### new Parser(keywordspec) | ||
#### new Parser(keywordSpec) | ||
Creates a new parser. | ||
The `keywordspec` parameter is optional, with the default being: | ||
The `keywordSpec` parameter is optional, with the default being: | ||
```javascript | ||
{ | ||
gettext: ['msgid'], | ||
_: ['msgid'], | ||
ngettext: ['msgid', 'msgid_plural'], | ||
n_: ['msgid', 'msgid_plural'], | ||
pgettext: ['msgctxt', 'msgid'], | ||
p_: ['msgctxt', 'msgid'], | ||
npgettext: ['msgctxt', 'msgid', 'msgid_plural'], | ||
np_: ['msgctxt', 'msgid', 'msgid_plural'] | ||
_: { | ||
msgid: 0 | ||
}, | ||
gettext: { | ||
msgid: 0 | ||
}, | ||
dgettext: { | ||
msgid: 1 | ||
}, | ||
dcgettext: { | ||
msgid: 1 | ||
}, | ||
ngettext: { | ||
msgid: 0, | ||
msgid_plural: 1 | ||
}, | ||
dngettext: { | ||
msgid: 1, | ||
msgid_plural: 2 | ||
}, | ||
pgettext: { | ||
msgctxt: 0, | ||
msgid: 1 | ||
}, | ||
dpgettext: { | ||
msgctxt: 1, | ||
msgid: 2 | ||
} | ||
} | ||
``` | ||
Each keyword (key) requires array of strings indicating the order of expected PO fields. | ||
For example `npgettext: ['msgctxt', 'msgid', 'msgid_plural']` indicates that the | ||
`npgettext` handlebars helper takes arguments of form `{{npgettext "context" "string" "plural" ...}}` | ||
Each keyword (key) requires an object with argument positions. The `msgid` position is required. `msgid_plural` and `msgctxt` are optional. | ||
For example `gettext: {msgid: 0}` indicates that the Handlebars expression looks like `{{gettext "string"}}`. | ||
@@ -32,0 +48,0 @@ #### .parse(template) |
9443
987
159
78