Skip to content

Commit c1b9519

Browse files
author
Kamil Tunkiewicz
committed
bugfixes
1 parent fec5096 commit c1b9519

File tree

3 files changed

+56
-17
lines changed

3 files changed

+56
-17
lines changed

README.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Webpack Extract Translation Keys Plugin (Regex version)
22

3-
> This plugin was inspired by [webpack-extract-translation-keys](https://github.com/grassator/webpack-extract-translation-keys). It works in a completely different way, but it shares the concept and some of the source code, so I leave the original copyright info in files.
3+
> This plugin is based on [webpack-extract-translation-keys](https://github.com/grassator/webpack-extract-translation-keys). It works in a completely different way, but it shares the concept and some of the source code, so I leave the original copyright info in files.
44
55
Webpack provides an official plugin for managing translation using [i18n-webpack-plugin](https://github.com/webpack/i18n-webpack-plugin), but in only allows for build-time translations by replacing strings in the source code.
66

@@ -121,14 +121,19 @@ Default value: `/gettext\(\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)(")|'([^'\\]*(?:\\.[^'\
121121

122122
This should be a regular expression object or simply a string. Plugin will internally enforce "g" and "m" flags on the provided regexp.
123123

124-
The expression must have at least one outputting group block. By default the first group block one is considered to be the translation key.
124+
The expression must have at least one outputting group block.
125+
126+
By default the first and third group block one is considered to be the translation key. That's because of the default `functionPattern` that matches two versions of `gettext` - with `"` and `'` quotes used.
127+
125128
You can change this to be any block by modifying the `groupIndex` option.
126129

127130
#### - `groupIndex`
128131

129-
Default value: 1
132+
Default value: [1, 3]
130133

131-
Specifies which group block from `functionPattern` contains the translation key.
134+
Specifies which group block from `functionPattern` contains the translation key. This can be integer or array of integers.
135+
136+
If multiple indexes are provided - the first group which returns a value will be used. At least one group must return value unless plugin will throw an error.
132137

133138
#### - `moduleFilter`
134139

@@ -247,10 +252,12 @@ Enables mangling of translation keys. When enabled the `functionReplace` option
247252

248253
#### - `functionReplace`
249254

250-
Default value: `gettext($2$1$2`
255+
Default value: `gettext($2$4$1$3$2$4`
251256

252257
This option specifies the replacement for the `functionPattern` when mangling translation keys. It is required if you use mangling.
253258

259+
Please note that if some group returns `undefined` it is changed to empty string, so you can easily use output from multiple groups even if they don't match anything in the string.
260+
254261
You can also use this option to change the function name if you like to.
255262

256263
#### - `done`

index.js

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,20 @@ var fs = require('fs');
2626
*/
2727
function ExtractTranslationRegexPlugin(options) {
2828
options = options || {};
29-
if (options.functionPattern && !options.functionReplace) {
30-
throw new Error("ExtractTranslationRegexPlugin: If you provide functionPattern, you must provide functionReplace");
31-
}
3229
this.functionPattern = options.functionPattern || /gettext\(\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)(")|'([^'\\]*(?:\\.[^'\\]*)*)('))/gm;
33-
this.functionReplace = options.functionReplace || 'gettext($2$1$2';
34-
this.groupIndex = 1;
30+
this.functionReplace = options.functionReplace || 'gettext($2$4$1$3$2$4';
31+
this.groupIndex = options.groupIndex || [ 1, 3 ];
3532
this.done = options.done || function () {};
3633
this.output = typeof options.output === 'string' ? options.output : false;
3734
this.mangle = options.mangle || false;
3835
this.moduleFilter = options.moduleFilter || [ /((?:[^!?\s]+?)(?:\.js|\.jsx|\.ts))$/, /^((?!node_modules).)*$/ ]
36+
37+
if (options.functionPattern && !options.functionReplace) {
38+
throw new Error("ExtractTranslationRegexPlugin: If you provide functionPattern, you must provide functionReplace");
39+
}
40+
if (typeof this.groupIndex !== 'object') {
41+
this.groupIndex = [ this.groupIndex ];
42+
}
3943
}
4044

4145
ExtractTranslationRegexPlugin.prototype.apply = function(compiler) {
@@ -59,15 +63,16 @@ ExtractTranslationRegexPlugin.prototype.apply = function(compiler) {
5963
// iterating keys found in module
6064
var match;
6165
while ((match = regex.exec(source)) !== null) {
62-
if (!match[this.groupIndex]) {
66+
var keyIndex = getKeyIndexFromMatch(match, this.groupIndex);
67+
if (keyIndex === -1) {
6368
compilation.errors.push(
6469
new Error("ExtractTranslationRegexPlugin: The provided `functionPattern` regular expression do not contain capture block. Please check your webpack.config.js file.")
6570
);
6671
return false;
6772
}
6873

6974
var original = match[0];
70-
var value = match[this.groupIndex];
75+
var value = match[keyIndex];
7176
var key = value;
7277

7378
// saving translation key per module
@@ -83,14 +88,25 @@ ExtractTranslationRegexPlugin.prototype.apply = function(compiler) {
8388
if (this.mangle) {
8489
// build the replacement with new (mangled) key
8590
var replacement = this.functionReplace;
86-
var tmpMatch = match;
87-
tmpMatch[this.groupIndex] = key;
91+
var tmpMatch = match.slice(0);
8892
for (var i = 1; i < tmpMatch.length; i++) {
89-
replacement = replacement.replace(new RegExp('\$' + i, 'g'), tmpMatch[i])
93+
if (typeof tmpMatch[i] == 'undefined') {
94+
tmpMatch[i] = '';
95+
} else {
96+
// if the match is translation key
97+
if (this.groupIndex.indexOf(i) !== -1) {
98+
if (i == keyIndex) {
99+
tmpMatch[i] = key;
100+
} else {
101+
tmpMatch[i] = '';
102+
}
103+
}
104+
}
105+
replacement = replacement.replace(new RegExp('\\$' + i, 'g'), tmpMatch[i])
90106
}
91107
source = source.replace(
92108
new RegExp(sanitizeForRegexp(original), 'gm'),
93-
this.functionReplace
109+
replacement
94110
);
95111
}
96112
}
@@ -200,4 +216,20 @@ var flipObject = function (obj) {
200216
return newObj;
201217
};
202218

219+
/**
220+
* Gets translation key from match according to `groupIndex` data
221+
* @param {Array} match
222+
* @param {Array} groupIndex
223+
* @returns {int}
224+
*/
225+
var getKeyIndexFromMatch = function(match, groupIndex) {
226+
for (var i in groupIndex) {
227+
var index = groupIndex[i];
228+
if (match[index]) {
229+
return index;
230+
}
231+
}
232+
return -1;
233+
};
234+
203235
module.exports = ExtractTranslationRegexPlugin;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "webpack-extract-translation-keys-regex-plugin",
3-
"version": "1.0.0",
3+
"version": "1.0.1",
44
"description": "Webpack plugin to extract list of used translation keys from included modules, using regular expressions.",
55
"main": "index.js",
66
"files": [

0 commit comments

Comments
 (0)