-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
195 lines (157 loc) · 4.83 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
// Module Loading
var path = require('path');
var through = require('through2');
var gtxParser = require("gettext-parser");
var File = require('vinyl');
var Concat = require('concat-with-sourcemaps');
var PluginError = require('plugin-error');
var utils = require('./src/helpers.js');
// Const
const PLUGIN_NAME = 'gulp-gettext-php-tpl';
// Main method to generate a POT file from a lot of files
// Uses modified concatenation logic from gulp-concat
function generatePOT(file, opts) {
// Default Options and override
var options = {
project : 'PROJECT',
company : 'COMPANY',
package : 'PACKAGE'
};
if(opts && typeof opts === 'object')
options = Object.assign(options, opts);
// File missing throw error
if (!file) {
throw new PluginError(PLUGIN_NAME, 'Missing file option');
}
// Concat declaration
var latestFile;
var latestMod;
var fileName;
var concat;
// Switch filename
if (typeof file === 'string') {
fileName = file;
} else if (typeof file.path === 'string') {
fileName = path.basename(file.path);
} else {
throw new PluginError(PLUGIN_NAME, 'Missing path in file options');
}
// Buffering function
function bufferContents(file, enc, cb) {
// Ignore empty files
if (file.isNull()) {
cb();
return;
}
// Remove streams
if (file.isStream()) {
this.emit('error', new PluginError(PLUGIN_NAME, 'Streaming not supported'));
cb();
return;
}
// Set latest file if not already set,
// or if the current file was modified more recently.
if (!latestMod || file.stat && file.stat.mtime > latestMod) {
latestFile = file;
latestMod = file.stat && file.stat.mtime;
}
// Construct concat instance
if (!concat) {
concat = new Concat(false, fileName, '\n');
}
// Get the extension - .TPL are Smarty Templates, .PHP are classes
var ext = file.path.split('.').pop().toLowerCase();
// Check that the file is .php or .tpl
if (ext === "php" || ext === "tpl") {
// All translatable strings holder
var holder = "";
// Switch PHP and TPL
var regex = null;
if (ext === "tpl") {
// Regex for Smarty TPL Matching
regex = new RegExp('(?:{t)(?:.*?})(.*?)(?={\\/t})', 'g');
}
else {
// Regex for PHP Gettext Matching
regex = new RegExp('(?:_\\(\')(.*?)(?:\'\\)(?:;|,))', 'g');
}
// Iterate the matches
while ((match = regex.exec(file.contents.toString())) != null) {
// Get the string and make some string fixes to match original style
var string = match[1];
string = utils.stripslashes(string);
string = string.replace(/[\r\n]+/g, "");
string = string.replace(/\\([\s\S])|(")/g, "\\$1$2");
// Put into holder
holder += string + "\n";
}
// Remove last \n
holder = holder.substr(0, holder.length - 1);
// Make new buffer from holder content and send it to concat instance
concat.add(file.relative, new Buffer(holder), file.sourceMap);
// Callback
cb();
}
else {
// File is not a .tpl or .php - Ignore!
cb();
}
}
// Ending method, wrap the POT
function endStream(cb) {
// No files passed in, no file goes out
if (!latestFile || !concat) {
cb();
return;
}
// Declare the final POT file
var potFile;
// If file opt was a file path
// clone everything from the latest file
if (typeof file === 'string') {
potFile = latestFile.clone({contents: false});
potFile.path = path.join(latestFile.base, file);
} else {
potFile = new File(file);
}
// Translate the concat in array and sort alphabetically
var tradArray = concat.content.toString().split("\n").sort();
// Remove duplicates and empty ones
var uniques = {};
uniques = tradArray.filter(function (item) {
if (item === undefined) return false;
if (item === '') return false;
return uniques.hasOwnProperty(item) ? false : (uniques[item] = true);
});
// Build the POT File content
var potContent = utils.generatePotHeader(options) + '\nmsgid "' +
uniques.join('"\nmsgstr ""\n\nmsgid "')
+ '"\nmsgstr ""\n';
// Set the POT file new content and push it downstream
potFile.contents = new Buffer(potContent);
this.push(potFile);
cb();
}
// Initialize the pipe
return through.obj(bufferContents, endStream);
}
// Takes a potFile from the stream in and creates a .po file
// Passes over the potFile to the stream
function mergeAndMake(targetFile) {
if (!targetFile) {
throw new PluginError(PLUGIN_NAME, 'Target file path is required');
}
return through.obj(function (file, enc, callback) {
// Load the potFile from the stream
var potFile = gtxParser.po.parse(file.contents.toString());
// Makes PO and MO files from old PO and the new POT
utils.makePoMo(targetFile, potFile);
// Callback and passes over the original file
callback(null, file);
})
}
// Exporting the plugin main functions
module.exports = {
mergeAndMake: mergeAndMake,
generatePOT: generatePOT
}